Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Python2 auf 3: Matheberechnungen

5 views
Skip to first unread message

Stephan Seitz

unread,
Aug 18, 2020, 4:09:31 AM8/18/20
to
Hallo!

Ich versuche gerade, das völlig unnötige ;-) Python-Script AstroBuild
(https://github.com/lhartikk/AstroBuild) auf Python3 zu migrieren.

Dabei stelle ich aber fest, daß die verwendeten mathematischen
Funktionen teilweise zu anderen Ergebnissen kommen.

Eine Funktion berechnet z.B. aus Jahr, Monat, Tag und Stunde den folgenden
Wert:
return 367*year - 7 * ( year + (month+9)/12 ) / 4 + 275*month/9 + day - 730530 + float(hour)/float(24)

Python2 kommt aktuell auf 7536.33333333, Python3 auf 7535.298611111201.
Da dieser Wert für weitere Berechnungen verwendet wird, komme ich nie
auf identische Ergebnisse.

Woran liegt das? Und wie portiert man dann so ein Script?

Shade and sweet water!

Stephan

--
| Stephan Seitz E-Mail: stse+...@rootsland.net |
| If your life was a horse, you'd have to shoot it. |


Hartmut Goebel

unread,
Aug 18, 2020, 4:48:12 AM8/18/20
to
Am 18.08.20 um 10:09 schrieb Stephan Seitz:
> Eine Funktion berechnet z.B. aus Jahr, Monat, Tag und Stunde den folgenden
> Wert:
> return 367*year - 7 * ( year + (month+9)/12 ) / 4 + 275*month/9 + day - 730530 + float(hour)/float(24)
>
> Python2 kommt aktuell auf 7536.33333333, Python3 auf 7535.298611111201.
> Da dieser Wert für weitere Berechnungen verwendet wird, komme ich nie
> auf identische Ergebnisse.
>
> Woran liegt das? Und wie portiert man dann so ein Script?

Der Operator / hat sich geändert (siehe
https://www.python.org/dev/peps/pep-0238/)

In Python 2 hat / Ganzzahlen so geteilt, dass nur der ganzzahlige Teil
geliefert wurde ("floor operator)

>>> (month+9)/12
1

In Python 3 teilt / auch Ganzzahlen "echt":

>>> (month+9)/12
1.4166666666666667

Um nur den ganzzahligen Teil zu bekommen, verwende //:

>>> (month+9)//12
1

Deine Formal muss also lauten

367*year - 7 * ( year + (month+9)//12 ) // 4 + 275*month//9 + day -
730530 + float(hour)/float(24)
>>> (month+9)//12

BTW 1: "float(24) kannst Du klarere als "24." schreiben
BTW 2: Da Du durch "24." oder "float(24)" teilst, kannst Du Dir das
"float" bei "hour" sparen
BTW 3: Da "/" in Python 3 sowieso "Reste" liefert, genügt auch "hour/24"


--
Schönen Gruß
Hartmut Goebel
Dipl.-Informatiker (univ), CISSP, CSSLP, ISO 27001 Lead Implementer
Information Security Management, Security Governance, Secure Software
Development

Goebel Consult, Landshut
http://www.goebel-consult.de

Blog: https://www.goe-con.de/blog/chatsecure-ist-tot-lang-lebe-chatsecure
Kolumne:
https://www.goe-con.de/hartmut-goebel/cissp-gefluester/2011-08-horrorszenario-bring-your-own-device


Peter Otten

unread,
Aug 18, 2020, 4:56:40 AM8/18/20
to
Am Di August 18 2020, 08:09:29 schrieb Stephan Seitz:
> Hallo!
>
> Ich versuche gerade, das völlig unnötige ;-) Python-Script AstroBuild
> (https://github.com/lhartikk/AstroBuild) auf Python3 zu migrieren.
>
> Dabei stelle ich aber fest, daß die verwendeten mathematischen
> Funktionen teilweise zu anderen Ergebnissen kommen.
>
> Eine Funktion berechnet z.B. aus Jahr, Monat, Tag und Stunde den folgenden
> Wert:
> return 367*year - 7 * ( year + (month+9)/12 ) / 4 + 275*month/9 + day -
> 730530 + float(hour)/float(24)
>
> Python2 kommt aktuell auf 7536.33333333, Python3 auf 7535.298611111201.
> Da dieser Wert für weitere Berechnungen verwendet wird, komme ich nie
> auf identische Ergebnisse.
>
> Woran liegt das?

In Python 2 kommt es auf den Typ der Operanden an -- bei der Division zweier
int ist das Ergebnis wieder ein int, in allen anderen Fällen ein float:

# py2
>>> 7/2
3
>>> 7./2
3.5

In Python 3 ist das Ergebniss immer ein float:

# py3
>>> 7/2
3.5


> Und wie portiert man dann so ein Script?

Du musst die Divisionen identifizieren, bei denen sowohl Dividend als auch
Divisor ganzzahlig sind, und dort den Operator / durch // ersetzen:

# py3 und py2, i. e. die Änderung ist rückwärtskompatibel
>>> 7//2
3

PS: Du kannst das Verhalten von py3 in py2 erzwingen mit

# py2
>>> 7/2
3
>>> from __future__ import division
>>> 7/2
3.5

Stephan Seitz

unread,
Aug 18, 2020, 7:00:33 AM8/18/20
to
Hartmut Goebel <h.go...@goebel-consult.de> wrote:
> Der Operator / hat sich geändert (siehe
> https://www.python.org/dev/peps/pep-0238/)

Perfekt, danke dir und Peter für die schnelle Antwort.
Aktuell sieht mal alles gut aus.
0 new messages