Rückgabewert Val("340123451234567895")

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
Krause
UDF-Programmierer
UDF-Programmierer
Beiträge: 52
Registriert: Mo, 08. Jan 2007 8:55
Wohnort: In Thüringen

Rückgabewert Val("340123451234567895")

Beitrag von Krause »

Hi,

gibt es eine plausible Erklärung dafür, daß

Code: Alles auswählen

 Val("340123451234567895")
340123451234567900 zurück gibt?


MfG
Joachim
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

das liegt daran, dass es sich um eine Fließkomma Zahl handelt.
Die von dir gewählte Zahl ist so groß, dass Xbase++ diese nicht mehr ungerundet darstellen kann. Bei etwa 18 Stellen ist Schluss.

Ähnliches tritt auf wenn du Zahlenvergleiche machst:

45 = 45 // beide Zahlen sind klein genug und haben kein Komma also werden sie intern als integer behandelt (habe ich vor kurzem gelesen).

45. <> 45 // sobald ein Komma in der Zahl auftaucht, wird diese intern als Fließkommazahl behandelt und dann sind diese beiden nicht mehr gleich, auch wenn es anders aussieht.

round(45.0,0) = round(45,0) geht aber wieder.

Aus diesem Grunde rechnen Bankensysteme mit einem eigenen Datentyp für Währungen, den haben wir aber nicht (extrem großer Integer Datentyp, dessen rechte 2 Stellen als Nachkommastellen interpretiert werden.)

Tiefergehende Begründungen findest du hier:
http://de.wikipedia.org/wiki/Flie%C3%9Fkommazahl

oder bei der Suche im Forum zu "zahlen"
Gruß
Hubert
Krause
UDF-Programmierer
UDF-Programmierer
Beiträge: 52
Registriert: Mo, 08. Jan 2007 8:55
Wohnort: In Thüringen

Beitrag von Krause »

Hi Hubert,

danke für die schnelle Antwort. In meinem Fall war es kein Geldwert
(schön wärs :lol: ), es war eine NVE die ich mittels:

Code: Alles auswählen

IF cValue == LTrim(Str(Val(cValue))) 
...
auf "string complete digit" hin überprüfen wollte ...


MfG
Joachim
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Krause hat geschrieben:es war eine NVE die ich mittels:
...
auf "string complete digit" hin überprüfen wollte ...
bei NVE steh ich jetzt auf dem Schlauch, aber um zu Prüfen ob nur Ziffern im String sind, bleibt nichts übrig als eine Funktion:

Code: Alles auswählen

function IsStringCompleteDigit(cStringNumVar, cErlaubteZeichen)
    local lOK := .t., x, nMaxLen := len(cStringNumVar)
    for x := 1 to nMaxLen 
         if ! cStringNumVar[x] $ cErlaubteZeichen
            lOK := .f.
            exit
         endif
     next
return lOK
Gruß
Hubert
Krause
UDF-Programmierer
UDF-Programmierer
Beiträge: 52
Registriert: Mo, 08. Jan 2007 8:55
Wohnort: In Thüringen

Beitrag von Krause »

Hi Hubert,

NVE = Nummer der Versandeinheit entsprechende EAN 128, es dürfen
nur Ziffern enthalten sein ... ähnliche Problematik auch bei EAN 8 oder
EAN 13 Materialummern.

Meine schnelle Lösung war :

Code: Alles auswählen

//---------------------------------------------------
METHOD SYSC0A05:IsStringDigit(cValue)
//---------------------------------------------------

LOCAL iCounter:=1, iLen:=0, cDy:=""

 IF ! Valtype(cValue)=="C"
  RETURN FALSE
 ENDIF

 cValue:=AllTrim(cValue); iLen:=Len(cValue)

 DO WHILE TRUE
  IF iCounter > iLen
   EXIT
  ENDIF
  cDy:=SubStr(cValue,iCounter,1)
  IF ! IsDigit(cDy)
   RETURN FALSE
  ENDIF
  iCounter ++
 ENDDO

RETURN TRUE

//---------------------------------------------------
MfG
Joachim
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

wie auch immer, aber du machst oben ein alltrim(cValue).
Ist die Länge nicht auch festgeschrieben ?
Gruß
Hubert
Krause
UDF-Programmierer
UDF-Programmierer
Beiträge: 52
Registriert: Mo, 08. Jan 2007 8:55
Wohnort: In Thüringen

Beitrag von Krause »

Hi Hubert,

die NVE kann von überall herkommen (SLE, Datenbank, XML, IDOC, Scannvorgang etc.), aus diesem Grund das AllTrim().
Normaler Weise hat eine NVE 18 Stellen (Digit's) inklusive Prüfziffer (PZ), diese PZ kontrolliere ich an einer anderen Stelle ...

MfG
Joachim
Antworten