|
|||
|
Hi all,
I've searched the newsgroup regarding the subject of my message but haven't found the answer, so I need you're help. Here's the example: String: 1201000030921111100 I need to convert string this length to integer, and then to use Mod() function: Mod(1201000030921111100,97) which using windows calculator returns: 39 The problem occurs when I try to use Val() function - I get the number: 12010000309211111000 - with extra 0 in the end. So, Mod(,97) returns 76 instead 39. I've seen Frans de Witt CPU Class, but haven't been able to implement it. I would appreciate your's help. Regards, Milun Vasilijevic |
|
|
||||
|
||||
|
|
|
|||
|
Milun
> The problem occurs when I try to use Val() function - I get the number: > 12010000309211111000 - with extra 0 in the end. So, Mod(,97) returns 76 > instead 39. No idea how you got that - all I get is a numeric overflow error (ie the text/number is to big for a 32bit value) If it came from a 64bit system then you'll need 64bit routines to handle it. VO isn't a 64bit system and more than likely never will be<bg> You might try using Vulcan to do the conversion, I believe .NET can handle 64bit numerics. CYA Steve |
|
|||
|
On 13/07/2012 02:36, Milun Vasilijevic wrote:
> Hi all, > > I've searched the newsgroup regarding the subject of my message but haven't found the answer, so I need you're help. Here's the example: > > String: 1201000030921111100 > > I need to convert string this length to integer, and then to use Mod() function: First of all, as noted, that number is too large to fit into a VO integer (largest value in a 32 bit signed integer 2147483648==2^32-1) You are even running close to the limit of 64 bit integers 1201000030921111100 your number 9223372036854775807==2^63-1 which strongly suggests that the 64 bit float that is used by val cannot be exact (I think an IEEE 64 bit real8 has about 48 bits of accurancy? ), which means it is meaningless to use mod > Mod(1201000030921111100,97) > > which using windows calculator returns: 39 > > The problem occurs when I try to use Val() function - I get the number: 12010000309211111000 - with extra 0 in the end. So, Mod(,97) returns 76 instead 39. yes - this is the expected result because there is no datatype in VO that can exactly store that number. probably the most important question is whether a 64 bit int would be enough or whether you have to use arbitrary precision classes instead. |
|
|||
|
On 13/07/2012 09:38, Malcolm G wrote:
> On 13/07/2012 02:36, Milun Vasilijevic wrote: >> Hi all, >> >> I've searched the newsgroup regarding the subject of my message but haven't found the answer, so I need you're help. Here's the example: >> >> String: 1201000030921111100 >> >> I need to convert string this length to integer, and then to use Mod() function: As someone else has pointed out you may well be using IBANS. If you are specifically doing that, this code may be some help, no warrently but I assume you can see why it works. static function Remainder97 (cCheck as string) as int local retval as int IF LEN (cCheck) < 9 retval := VAL (cCheck) retval := retval % 97 ELSE retval := Remainder97 (TrimStr (Remainder97 (Left (cCheck, 8))) + Substr (cCheck, 9)) ENDIF return retval |
|
|||
|
Hi Paolo,
> Great Function, in Portugal the 21 digits on the right are the NIB, any idea to validate only these digits? Sorry NO. But a really good function is Remainder97 from Malcolm - Congratulation. Best will be to combine these 2 functions. Norbert |
|
|||
|
I can also offer some IBAN Check code using the arithmetic of an Oracle
database. Arne Ortlinghaus ACS Data Systems method ValidateIBAN(cIBANChar as string) class clsIBAN local cIBANTmp1, cIBANTmp2, cChar, cSql as string local iPos as dword local nChDig as usual if ascan(_aLaender,left(cIBANChar,2)) == 0 return true end if cIBANChar := AllTrim(cIBANChar) // Todo 66425 AO 12.07.2012 Runtimefehler bei IBAN-Prfung im Falle von falschen Zeichen cIBANTmp1 := substr(cIBANChar,5)+left(cIBANChar,4) cIBANTmp2 := "" for iPos := 1 to slen(cIBANTmp1) cChar := substr(cIBANTmp1,iPos,1) if ! isdigit(string2psz(cChar)) cChar := str(asc(cChar)-55,2) end if cIBANTmp2 += cChar next if !Empty(Val(cIBANTmp2)) // Todo 63367 Fehlermeldung bei Import IBAN in Kunden/Lieferanten cSql := 'SELECT MOD('+SQLValue2SQLString(cIBANTmp2)+',97) "Modulus" FROM DUAL' nChDig := GetSQLValueFast(cSql, "N", 10, 0, 0, null_object, true) else nChDig := 0 endif //msginfo(cIBANChar+chr(13)+chr(10)+cIBANTmp1+chr(13 )+chr(10)+cIBANTmp2+chr(13)+chr(10)+cSql+chr(13)+c hr(10)+typevalue2string(nChDig)) return nChDig == 1 method Init(oOwner, oServer) class clsIBAN _oOwner := oOwner _oServer := oServer _aLaender := ArrayCreate(18) _aLaengen := ArrayCreate(18) _aLaender[1] := "IT" _aLaengen[1] := 27 _aLaender[2] := "AT" _aLaengen[2] := 20 _aLaender[3] := "BE" _aLaengen[3] := 16 _aLaender[4] := "CH" _aLaengen[4] := 21 _aLaender[5] := "DE" _aLaengen[5] := 22 _aLaender[6] := "DK" _aLaengen[6] := 18 _aLaender[7] := "ES" _aLaengen[7] := 24 _aLaender[8] := "FI" _aLaengen[8] := 18 _aLaender[9] := "FR" _aLaengen[9] := 27 _aLaender[10] := "GB" _aLaengen[10] := 22 _aLaender[11] := "IE" _aLaengen[11] := 22 _aLaender[12] := "IS" _aLaengen[13] := 26 _aLaender[13] := "LU" _aLaengen[13] := 20 _aLaender[14] := "NL" _aLaengen[14] := 18 _aLaender[15] := "NO" _aLaengen[15] := 15 _aLaender[16] := "PT" _aLaengen[16] := 25 _aLaender[17] := "SE" _aLaengen[17] := 24 _aLaender[18] := "SM" _aLaengen[18] := 27 return self class clsIBAN protect _oOwner as object protect _oServer as object protect _aLaender as array protect _aLaengen as array declare method ValidateIBAN |
|
|||
|
Hi Norbert, Malcom, and everybody who came to the rescue,
Thank you for your time, you've been very helpful. In the end I implementedMalcom's great function Remainder97. You were right - I needed this function for digit checking in my e-banking payment order module. It wasn't IBAN numbers but rather similar thing: adding control number to the reference number of payment order. Once again thank you very much. Milun Vasilijevic петак, 13. јул 2012. 16.59.10 UTC+2, Norbert Kolb је написао/ла: > Hi Paolo, > > > Great Function, in Portugal the 21 digits on the right are the NIB, > any idea to validate only these digits? > > Sorry NO. > > But a really good function is Remainder97 from Malcolm - Congratulation. > Best will be to combine these 2 functions. > > Norbert |
|
|||
|
One more thing. It was ISO 7064 Mod 97,10 standard I had to implement:
http://code.google.com/p/checkdigits...ckDigitSystems Milun |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|