October 24, 2021, 03:07:40

Author Topic: [bb] BlitzMax Big Numbers by Spencer [ 1+ years ago ]  (Read 619 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] BlitzMax Big Numbers by Spencer [ 1+ years ago ]
« on: June 29, 2017, 00:28:41 »
Title : BlitzMax Big Numbers
Author : Spencer
Posted : 1+ years ago

Description : The code below represents a set of functions for BlitzMax that can be used to add and subtract big integers without loss of precision. Values are stored in decimal format as strings.(x ="42" )  The code below has both the functions and a simple program demonstrating the addition and subtraction functions. The subtraction function is simplified by using the nine's complement (see Wikipedia: Method of complements) of the minuend. Basically, it's a math trick that allows the function the calculate subtraction by doing addition. It avoids the need to "borrow" when subtracting. Currently, this version can only handle positive integers. One possible use of these functions is to keep track of a player's very large score without loss of precision. This code has not been rigorously tested. So, if you find any bugs, please post them in the comments below.
Thanks,
Spencer


Code :
Code: BlitzBasic
  1. '-------------------------------------------------
  2. 'Example Program
  3.  
  4.         Global x:String = "0"
  5.         Global y:String = "0"
  6.         Global R:String = "0"
  7.        
  8.         x = "9999999999999999999999999999999999999"
  9.         y = "1"
  10.         R = BigNumbers.Add(x,y)
  11.         Print R
  12.        
  13.         x = "11900"
  14.         y = "11800"
  15.         R = BigNumbers.Subtract(x,y)
  16.         Print R
  17.        
  18. End
  19. '-------------------------------------------------
  20.  
  21.  
  22.  
  23. '***************************************************************************************************************
  24. 'BigNumbers
  25. '***************************************************************************************************************
  26. Type BigNumbers
  27.  
  28.         Const EnumCompareResultLessThan = -1
  29.         Const EnumCompareResultEqualTo = 0
  30.         Const EnumCompareResultGreaterThan = 1
  31.  
  32.         Function GetNinesComplement:String(Value:String,MinuendDigitCount:Int)
  33.                 Local Result:String
  34.                 For Local CharPos:Int = 0 To Value.Length-1  Step 1
  35.                         Result = Result + Trim(String( 9-Int(Chr(Value[CharPos]))) )   
  36.                 Next
  37.                 While Result.Length < MinuendDigitCount
  38.                         Result = "9" + Result
  39.                 Wend
  40.                 Return Result
  41.         EndFunction
  42.  
  43.         Function StringPadLeft:String(SourceValue:String,Value:String,Count:Int)
  44.                 For Local x:Int = 1 To Count Step 1
  45.                         SourceValue = Value + SourceValue
  46.                 Next
  47.                 Return SourceValue     
  48.         EndFunction
  49.        
  50.         Function StripLeadingZeros:String(Value:String)
  51.                 For Local CharPos:Int = 0 To Value.Length-1 Step 1
  52.                         If( Chr(Value[CharPos]) <> " " ) And ( Chr(Value[CharPos]) <> "0" ) Then
  53.                                 Return Trim(Value[CharPos..])
  54.                         EndIf
  55.                 Next
  56.                 Return "0" 'value was all spaces and/or zeros
  57.         EndFunction
  58.        
  59.         Function CompareNumbers:Int(Number1:String,Number2:String)
  60.                 Local Difference:Int = Number2.Length - Number1.Length
  61.                 Local Number1Padded:String = BigNumbers.StringPadLeft(Number1,"0",(Difference>0)*Difference)
  62.                 Local Number2Padded:String = BigNumbers.StringPadLeft(Number2,"0",(Difference<0)*(Abs(Difference)))
  63.                 Local Digit1:Byte
  64.                 Local Digit2:Byte
  65.                 For Local CharPos:Int = 0 To Number1Padded.Length-1 Step 1
  66.                         Digit1 = Int(Chr(Number1Padded[CharPos]))
  67.                         Digit2 = Int(Chr(Number2Padded[CharPos]))
  68.                         If(Digit1 > Digit2)Then
  69.                                 Return BigNumbers.EnumCompareResultGreaterThan
  70.                         ElseIf(Digit2 > Digit1)Then
  71.                                 Return BigNumbers.EnumCompareResultLessThan
  72.                         EndIf
  73.                 Next
  74.                 Return BigNumbers.EnumCompareResultEqualTo
  75.         EndFunction
  76.        
  77.         Function GetLargest:String(Number1:String,Number2:String)
  78.                 If(BigNumbers.CompareNumbers(Number2,Number1) = BigNumbers.EnumCompareResultGreaterThan)Then
  79.                         Return Number2
  80.                 Else
  81.                         Return Number1
  82.                 EndIf
  83.         EndFunction
  84.        
  85.         Function GetSmallest:String(Number1:String,Number2:String)
  86.                 If(BigNumbers.CompareNumbers(Number2,Number1) = BigNumbers.EnumCompareResultLessThan)Then
  87.                         Return Number2
  88.                 Else
  89.                         Return Number1
  90.                 EndIf
  91.         EndFunction
  92.  
  93.         Function Add:String(Number1:String,Number2:String)
  94.                 Local Difference:Int = Number2.Length - Number1.Length
  95.                 Local Number1Padded:String = BigNumbers.StringPadLeft(Number1,"0",(Difference>0)*Difference)
  96.                 Local Number2Padded:String = BigNumbers.StringPadLeft(Number2,"0",(Difference<0)*(Abs(Difference)))
  97.                 Local Result:String
  98.                 Local A:Byte
  99.                 Local B:Byte
  100.                 Local C:Byte
  101.                 Local R:Byte   
  102.                 For Local CharPos:Int = Number1Padded.Length-1 To 0 Step -1
  103.                         C = (R > 9)
  104.                         A = Int(Chr(Number1Padded[CharPos]))
  105.                         B = Int(Chr(Number2Padded[CharPos]))
  106.                         R = A + B + C
  107.                         Result = Right(String(R),1) + Result
  108.                 Next
  109.                 If(C > 0) Then
  110.                         Result = "1" + Result
  111.                 EndIf
  112.                 Return BigNumbers.StripLeadingZeros(Result)    
  113.         EndFunction
  114.        
  115.         Function Subtract:String(Number1:String,Number2:String)
  116.                 Local Smallest:String = BigNumbers.GetSmallest(Number1,Number2)
  117.                 Local Largest:String = BigNumbers.GetLargest(Number1,Number2)
  118.                 Local NinesComp:String = BigNumbers.GetNinesComplement(Smallest,Largest.Length)
  119.                 Local TempResult:String = BigNumbers.Add(Largest,NinesComp)  'nines complement of smaller number
  120.                 TempResult = BigNumbers.Add(TempResult,"1")
  121.                 TempResult = BigNumbers.StripLeadingZeros(TempResult)
  122.                 TempResult = TempResult[1..]
  123.                 Return BigNumbers.StripLeadingZeros(TempResult)
  124.         EndFunction
  125.  
  126. EndType
  127. '***************************************************************************************************************
  128. 'End of BigNumbers
  129. '***************************************************************************************************************


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal