Wo ist mein Fehler? Dezimal -> Binär

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Hi,

ich mache gerade die Morpheus-Challenges und finde bei mir einfach den Fehler nicht...
Irgendwie bekomme ich immer falsche binäre Zahlen raus, warum?
Habe mit bin(zahl) das mal gecheckt...

Mein Code:

Code: Alles auswählen

import json
import requests
import time


def loesung(url_chall_6, url_sol_6) -> object:
    roh = requests.get(url=url_chall_6)

    zahl = int(roh.text)
    solution = ""

    while zahl >= 1:
        binär = zahl % 2 #Modulo. Entweder 1 oder 0
        solution = str(binär) + solution #vorne dran hängen
        zahl = int(zahl / 2) #Zahl durch 2 teilen. Als int, damit bsp. =2.5 -> 2 wird.

    dat = {"token": solution}

    result = requests.post(url=url_sol_6, data=json.dumps(dat))
    print(result.text)  # success.ausgeben falls richtig


#Main
start = time.time()
m = 5
for i in range(m):
    loesung("https://cc.the-morpheus.de/challenges/6/", "https://cc.the-morpheus.de/solutions/6/")
print((time.time() - start) / m)
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Benutzeravatar
noisefloor
User
Beiträge: 3882
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

du hast keinen Fehler, der "Fehler" ist der Weg, wie (sehr) große Zahl im Rechner dargestellt werden und der damit verbunden Ungenauigkeit bzw. Rundungsfehlern.
Wenn du die Zahlen nicht als Integer sondern als `Decimal` aus dem `decimal` Modul darstellt, dann passt das Ergebnis auch.

Gruß, noisefloor
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

noisefloor hat geschrieben: Sonntag 26. August 2018, 20:36 Hallo,

du hast keinen Fehler, der "Fehler" ist der Weg, wie (sehr) große Zahl im Rechner dargestellt werden und der damit verbunden Ungenauigkeit bzw. Rundungsfehlern.
Wenn du die Zahlen nicht als Integer sondern als `Decimal` aus dem `decimal` Modul darstellt, dann passt das Ergebnis auch.

Gruß, noisefloor
Danke für deine Antwort.
Aber ich habe dann ja Dezimalzahlen, was ich ja für den Modulo nicht haben will. Ich muss ja immer abrunden, wenn ein krummes Ergebnis herauskommt. Also nicht 17/2 = 8.5 , sondern 17/2 = 8 ...
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kann man irgendwo die eigentliche Aufgabenstellung nachlesen? So ohne weiteres finde ich da nix.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Wenn es wirklich an der Rundung von sehr großen Zahlen liegt, dann solltest du versuchen, nur mit `int` zu rechnen. In Python 3 ist `/` gibt immer ein float zurück. Für integer-Division ist `//` vorgesehen. Ersetze also mal `zahl = int(zahl / 2)` durch `zahl = zahl // 2` (ungetestet).
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das mit dem runden stimmt nicht. Python beherrscht schon ewig beliebig große Ganzzahlen. Die genaue Version ist mir entfallen, aber der Code des TE läuft.
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Hier das Aufgabenvideo: https://www.youtube.com/watch?v=sdAXkE3 ... gs=pl%2Cwn

Es geht aber nicht darum die Aufgabe zu lösen, sondern es geht mir um den Code. Also warum das nicht funktioniert. :lol:

In der Regel sollte es ja für alles eine logische Erklärung geben...
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Benutzeravatar
noisefloor
User
Beiträge: 3882
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Aber ich habe dann ja Dezimalzahlen, was ich ja für den Modulo nicht haben will.
Du hast genau so Dezimalstellen wie jetzt auch und kannst genau so runden wie jetzt auch. Du hast nur die nötige Präzsion bei den großen Zahlen beim Dividieren:

Code: Alles auswählen

>>> from decimal import Decimal
>>> ausgangszahl = 2978847213262506705
>>> ausgangszahl/2
1.4894236066312532e+18
>>> Decimal(ausgangszahl)/2
Decimal('1489423606631253352.5')
>>>
Der Fehler / die Abwichung, die du bekommst, sind ja die ersten beiden Bits der Binärdarstellung, also für 2^0 und 2^1, also da, wo relativ große Zahlen dividiert werden.

Gruß, noisefloor
Sirius3
User
Beiträge: 17844
Registriert: Sonntag 21. Oktober 2012, 17:20

@noisefloor: der OP braucht gar keine Dezimalzahlen, sondern es reichen ganz normale Ganzzahlen, die auch schon beliebig groß werden dürfen. Wie boards0 schon geschrieben hat, liegt es an der falschen Division / statt //.

@naheliegend: wenn man sowohl Modulo als auch Division braucht, nimmt man am besten divmod. Laß das mal mit den Typannotationen sein, ein `-> object` ist ziemlich nutzlos zumal es hier ja als Rückgabewert nur Werte vom Typ NoneType gibt.

Code: Alles auswählen

def loesung(url_chall_6, url_sol_6):
    roh = requests.get(url=url_chall_6)
    zahl = int(roh.text)
    solution = ""
    while zahl >= 1:
        zahl, binär = divmod(zahl, 2)
        solution = str(binär) + solution
    dat = {"token": solution}
    result = requests.post(url=url_sol_6, data=json.dumps(dat))
    print(result.text)  # success.ausgeben falls richtig
Antworten