Posted: Tue Jan 16, 2007 9:32 pm
hmm, it will not be an easy step... i'll try.
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
; StrNumQ(Number.q [, Grouping.l [, ThousandSep.s]])
; StrNumD(Number.d [, Grouping.l [, ThousandSep.s [, DecimalSep.s [, NumDigits.l]]]])
EnableExplicit
Procedure.s StrNumQ(Number.q, Grouping.l = 3, ThousandSep.s = ",", Reserved1.s = "", Reserved2.s = "", Reserved3.l = 0)
If Not Reserved3
ProcedureReturn StrNumQ(0, Grouping, ThousandSep, StrQ(Number), "", 1)
EndIf
If Not Reserved1 Or Reserved1 = "-"
ProcedureReturn Reserved1 + Reserved2
EndIf
If Reserved3 = 2
Reserved2 = ThousandSep + Reserved2
EndIf
ProcedureReturn StrNumQ(0, Grouping, ThousandSep, Left(Reserved1, Len(Reserved1)-Grouping), Right(Reserved1, Grouping) + Reserved2, 2)
EndProcedure
Procedure.s StrNumD(Number.d, Grouping.l = 3, ThousandSep.s = ",", DecimalSep.s = ".", NumDigits.l = 4, Reserved1.s = "", Reserved2.s = "", Reserved3.l = 0)
If Not Reserved3
ProcedureReturn StrNumD(0, Grouping, ThousandSep, "", 0, StringField(StrD(Number), 1, "."), DecimalSep + StringField(StrD(Number, NumDigits), 2, "."), 1)
EndIf
If Not Reserved1 Or Reserved1 = "-"
ProcedureReturn Reserved1 + Reserved2
EndIf
If Reserved3 = 2
Reserved2 = ThousandSep + Reserved2
EndIf
ProcedureReturn StrNumD(0, Grouping, ThousandSep, "", 0, Left(Reserved1, Len(Reserved1)-Grouping), Right(Reserved1, Grouping) + Reserved2, 2)
EndProcedure
Debug "StrNumQ()" ;{
Debug StrNumQ(1234567890)
Debug StrNumQ(123456789)
Debug StrNumQ(12345678)
Debug StrNumQ(1234567)
Debug StrNumQ(123456)
Debug StrNumQ(12345)
Debug StrNumQ(1234)
Debug StrNumQ(123)
Debug StrNumQ(12)
Debug StrNumQ(1)
Debug StrNumQ(0)
Debug StrNumQ(-1)
Debug StrNumQ(-12)
Debug StrNumQ(-123)
Debug StrNumQ(-1234)
Debug StrNumQ(-12345)
Debug StrNumQ(-123456)
Debug StrNumQ(-1234567)
Debug StrNumQ(-12345678)
Debug StrNumQ(-123456789)
Debug StrNumQ(-1234567890)
Debug ""
;}
Debug "StrNumD()" ;{
Debug StrNumD(1234567890.12345)
Debug StrNumD(123456789.12345)
Debug StrNumD(12345678.12345)
Debug StrNumD(1234567.12345)
Debug StrNumD(123456.12345)
Debug StrNumD(12345.12345)
Debug StrNumD(1234.12345)
Debug StrNumD(123.12345)
Debug StrNumD(12.12345)
Debug StrNumD(1.12345)
Debug StrNumD(0.12345)
Debug StrNumD(-1.12345)
Debug StrNumD(-12.12345)
Debug StrNumD(-123.12345)
Debug StrNumD(-1234.12345)
Debug StrNumD(-12345.12345)
Debug StrNumD(-123456.12345)
Debug StrNumD(-1234567.12345)
Debug StrNumD(-12345678.12345)
Debug StrNumD(-123456789.12345)
Debug StrNumD(-1234567890.12345)
Debug ""
;}
End
Thanks for the correction Shardik... cut & paste will get you every timeShardik wrote:@Paul:
Thank you for your fine API example. But in the second example there is a small mistake. In order to actually use your defined NUMBERFMT structure you have to provide the pointer to this structure instead of Null:
Code: Select all
Procedure.s StrNumQ(NumberQ.q, Grouping.l = 3, ThousandSep.s = ",") ; 281
Protected GroupingNum.l = Pow(10, Grouping), NumberA.q, NumberS.s
While NumberQ / GroupingNum
NumberA = Abs(NumberQ)
NumberS = Str(NumberA % GroupingNum) + ThousandSep + NumberS
NumberQ / GroupingNum
Wend
NumberS = Str(NumberQ) + ThousandSep + NumberS
ProcedureReturn Left(NumberS, Len(NumberS) - 1)
EndProcedure
Debug "StrNumQ()" ;{
Debug StrNumQ(23487523465274653)
Debug StrNumQ(1234567890)
Debug StrNumQ(123456789)
Debug StrNumQ(12345678)
Debug StrNumQ(1234567)
Debug StrNumQ(123456)
Debug StrNumQ(12345)
Debug StrNumQ(1234)
Debug StrNumQ(123)
Debug StrNumQ(12)
Debug StrNumQ(1)
Debug StrNumQ(0)
Debug StrNumQ(-1)
Debug StrNumQ(-12)
Debug StrNumQ(-123)
Debug StrNumQ(-1234)
Debug StrNumQ(-12345)
Debug StrNumQ(-123456)
Debug StrNumQ(-1234567)
Debug StrNumQ(-12345678)
Debug StrNumQ(-123456789)
Debug StrNumQ(-1234567890)
Debug StrNumQ(-23487523465274653)
;}
Code: Select all
Debug StrNumQ_D(23487523465274653)
Code: Select all
Procedure.s groupQuad(number.q, groupLen.l=3, separator.s=",")
Protected num.s=StrQ(number), currentPackage.s=Right(num, groupLen), currentLen.l=Len(num)-Len(currentPackage), result.s=currentPackage
If currentLen
result=groupQuad(ValQ(Left(num, currentLen)), groupLen, separator)+separator+result
EndIf
ProcedureReturn ReplaceString(result, "0"+separator, "-")
EndProcedure
For n=1 To 5
Debug groupQuad(1234567890, n)
Debug groupQuad(123456789, n)
Debug groupQuad(12345678, n)
Debug groupQuad(1234567, n)
Debug groupQuad(123456, n)
Debug groupQuad(12345, n)
Debug groupQuad(1234, n)
Debug groupQuad(123, n)
Debug groupQuad(12, n)
Debug groupQuad(1, n)
Debug groupQuad(0, n)
Debug groupQuad(-1, n)
Debug groupQuad(-12, n)
Debug groupQuad(-123, n)
Debug groupQuad(-1234, n)
Debug groupQuad(-12345, n)
Debug groupQuad(-123456, n)
Debug groupQuad(-1234567, n)
Debug groupQuad(-12345678, n)
Debug groupQuad(-123456789, n)
Debug groupQuad(-1234567890, n)
Debug ""
Next
Code: Select all
Procedure.s StrNumQ(NumberQ.q, Grouping.l = 3, ThousandSep.s = ",")
Protected GroupingNum.l = Pow(10, Grouping), NumberS.s
While NumberQ / GroupingNum
NumberS = Str(IntQ(Abs(NumberQ)) % GroupingNum) + ThousandSep + NumberS
NumberQ / GroupingNum
Wend
NumberS = Str(NumberQ) + ThousandSep + NumberS
ProcedureReturn Left(NumberS, Len(NumberS) - 1)
EndProcedure
Procedure.s StrNumD(NumberD.d, Grouping.l = 3, ThousandSep.s = ",", DecimalSep.s = ".", NumDigits.l = 4)
ProcedureReturn StrNumQ(IntQ(NumberD), Grouping, ThousandSep) + DecimalSep + Left(StringField(StrD(NumberD), 2, "."), NumDigits)
EndProcedure
Code: Select all
Procedure.s FormatNumber(Number.Q)
Protected Buffer.S = Space(128)
GetNumberFormat_(#LOCALE_USER_DEFAULT, 0, StrQ(Number), 0, @Buffer, Len(Buffer))
ProcedureReturn Buffer
EndProcedure
SetLocaleInfo_(#LOCALE_USER_DEFAULT, #LOCALE_IDIGITS, @"0")
Debug FormatNumber(1234567890)
Code: Select all
SetLocaleInfo_(#LOCALE_USER_DEFAULT, #LOCALE_IDIGITS, @"0")
How to convert a integer-number (e. g. 12345) to a grouped integer WITHOUT decimals after the comma?Paul wrote:API version that uses system defaults for number formatting...Code: Select all
Procedure.s FormatNumber(Number.q) Buffer.s=Space(255) GetNumberFormat_(0,0,StrQ(Number),0,@Buffer,Len(Buffer)) ProcedureReturn Buffer EndProcedure
API version if you want to customize the formatting...Code: Select all
Procedure.s FormatNumber(Number.q) Buffer.s=Space(255) NF.NUMBERFMT\NumDigits=0 ;number of decimal places to use NF\Grouping=3 ;how many numbers before a seperator is used NF\lpDecimalSep=@"." ;decimal seperator character NF\lpThousandSep=@"," ;group seperator NF\NegativeOrder= 1 ;lookup LOCALE_INEGNUMBER for all options GetNumberFormat_(0,0,StrQ(Number),NF,@Buffer,Len(Buffer)) ProcedureReturn Buffer EndProcedure
Code: Select all
Procedure.s FormatNumber1(Number.q)
Protected Format.NUMBERFMT, NumberStr.s = Space(255)
Format\Grouping = 3
Format\lpDecimalSep = @"."
Format\lpThousandSep = @","
Format\NegativeOrder = 1
GetNumberFormat_(#Null, #Null, StrQ(Number), @Format, @NumberStr, Len(NumberStr))
ProcedureReturn NumberStr
EndProcedure
Procedure.s FormatNumber2(Number.q)
Protected NumberStr.s = Space(255)
GetNumberFormat_(#Null, #Null, StrQ(Number), #Null, @NumberStr, Len(NumberStr))
ProcedureReturn NumberStr
EndProcedure
Debug FormatNumber1(-12345) ; -12,345 (using format - own settings)
Debug FormatNumber2(-12345) ; -12 345,00 (no format, it use locale settings - here french)
AND51 wrote: How to convert a integer-number (e. g. 12345) to a grouped integer WITHOUT decimals after the comma?
I always get 12.345,00; but I don't want ,00 ...
@AND51AND51 wrote: Currently, you're setting decimal point (.) and separator (,) manually. That's the problem: This should be done automatically to prevent mistakes caused by different conventions.
Germans use "," as decimal point, the rest of the world uses ".". It's the same thing for separators but swapped: Germany = ".", the others ","
I can't do this automatically when working with the structure.
I had the same problem and have it solved already...Shardik wrote: It eliminates the need to define a complete NUMBERFMT structure only to get rid of the trailing two decimal places and the point/comma by using this API call: