A first attempt to handle decimal numbers in GCBasic. They work well in PIC18F2550 but should be tested in other MCUs. I hope to help some friends out there
Dim FirstFloat , SecondFloat , SysString , DecimalLength as String * 10
Dim IntegerPart1 , IntegerPart2 as String * 5
Dim DecimalPart1 , DecimalPart2 as String * 4
Dim DotSing as String * 1
Dim DecimalPart , IntegerPart as Word
Dim Multi1 , Multi2, Multi3 as Long
Dim SysStrDat as Byte
'Add two strings as Floating numbers and return the result as string
Function AddFloat (In FirstFloat(), In SecondFloat()) As String * 10 'Handle numbers up 65535.9999
Call Normalize ( FirstFloat() , SecondFloat())
DecimalPart=Val(DecimalPart1)
DecimalPart=DecimalPart+Val(DecimalPart2)
IntegerPart=Val(IntegerPart1)
IntegerPart=IntegerPart+Val(IntegerPart2)
DecimalLength=left(SysString , Len(DecimalPart1)+1)
if DecimalPart> Val(DecimalLength)-1 then
DecimalPart=DecimalPart % Val(DecimalLength)
IntegerPart=[Word]IntegerPart+1
End if
AddFloat = Str(IntegerPart) + DotSing
if DecimalPart<10 then SingLoc=3
if DecimalPart>=10 and DecimalPart<=99 then SingLoc=2
if DecimalPart>=100 and DecimalPart<=999 then SingLoc=1
if DecimalPart>=1000 then SingLoc=0
AddFloat=AddFloat+Right(SysString, SingLoc)
AddFloat = AddFloat + Str(DecimalPart)
for i=1 to 3
if Right(AddFloat,1)="0" then
AddFloat=Left(AddFloat, len(AddFloat)-1)
end if
next
End Function
'Multiply two strings as Floating numbers and return the result as string
Function MultiFloat ( In FirstFloat(), In SecondFloat()) As String * 10
DotSing="."
SingLoc=Instr(FirstFloat,DotSing)
IntegerPart1=Left(FirstFloat, SingLoc-1)
SingLoc=Instr(SecondFloat,DotSing)
IntegerPart2=Left(SecondFloat, SingLoc-1)
SingLoc=Len(FirstFloat)-Instr(FirstFloat,DotSing)
digit1=SingLoc
DecimalPart1=Right(FirstFloat, SingLoc )
SingLoc=Len(SecondFloat)-Instr(SecondFloat,DotSing)
digit2=SingLoc
DecimalPart2=Right(SecondFloat, SingLoc)
FirstFloat=IntegerPart1+DecimalPart1
SecondFloat=IntegerPart2+DecimalPart2
Multi1 = Val32(FirstFloat)
Multi2 = Val32(SecondFloat)
Multi3=Multi1Multi2
Multi1=1000000000
SysCharCount=0
Flag=0
For i=1 to 10
if Multi3>=Multi1 then
SysStrData = Multi3 / Multi1
Multi3 = Multi3- SysStrDataMulti1
SysCharCount += 1
SysString(SysCharCount) = SysStrData + 48
Flag=1
else
if Flag<>0 then
SysStrData=0
SysCharCount += 1
SysString(SysCharCount) = SysStrData + 48
end if
end if
Multi1=Multi1/10
Next
locate 0,0
print SysString
SysCharCount=len(SysString)
Do While SysString(SysCharCount)="0"
SysCharCount -=1
SysString(0)=SysCharCount
Loop
SingLoc=digit1+digit2
if SingLoc<SysCharCount then
MultiFloat=Left(SysString, SysCharCount-SingLoc)
MultiFloat=MultiFloat + "."
else
MultiFloat="0." + Mid("000000000",1,SingLoc-SysCharCount)
end if
MultiFloat=MultiFloat + Right(SysString, SingLoc)
End Function
'Converts a string to Long
Function Val32(SysInString as String) as Long
Val32=0
SysCharCount = SysInString(0)
For SysStringTemp = 1 to SysCharCount
SysStrData = SysInString(SysStringTemp)
Val32 = Val32 * 10 + SysStrData - 48
Next
end Function
'Converts two numbers in one string as Floating number
Function FloatToString (IntegerPart, DecimalPart) As String * 10
FloatToString = Str(IntegerPart) + "."
FloatToString = FloatToString + Str(DecimalPart)
end Function
'Extract the Integer part and the Decimal Part of Floating number in string
Sub StringToFloat ( In FirstFloat , Out IntegerPart , Out DecimalPart)
DotSing="."
SingLoc=Instr(FirstFloat,DotSing)
SecondFloat=Left(FirstFloat, SingLoc-1)
IntegerPart = Val(SecondFloat)
SingLoc=Len(FirstFloat)-Instr(FirstFloat,DotSing)
SecondFloat=Right(FirstFloat, SingLoc )
DecimalPart = Val(SecondFloat)
End Sub
Sub Normalize (FirstFloat() , SecondFloat())
DotSing="."
SysString="100000000"
SingLoc=Instr(FirstFloat,DotSing)
IntegerPart1=Left(FirstFloat, SingLoc-1)
SingLoc=Instr(SecondFloat,DotSing)
IntegerPart2=Left(SecondFloat, SingLoc-1)
SingLoc=Len(FirstFloat)-Instr(FirstFloat,DotSing)
DecimalPart1=Right(FirstFloat, SingLoc )
SingLoc=Len(SecondFloat)-Instr(SecondFloat,DotSing)
DecimalPart2=Right(SecondFloat, SingLoc)
if len(DecimalPart1)<=3 then
DecimalPart1=DecimalPart1+Right(SysString,4-len(DecimalPart1))
end if
if len(DecimalPart2)<=3 then
DecimalPart2=DecimalPart2+Right(SysString,4-len(DecimalPart2))
end if
End sub
The SubFloat Function for Subtraction. Anobium please correct the << stirngs>> from the title because it "hits" my eye.
'Subtract two strings as Floating numbers and return the result as string
'FirstFloat is the minuend and SecondFloat is the subtrahend
Function SubFloat (In FirstFloat(), In SecondFloat()) As String * 10
SingFlag1=0
SingFlag=0
Carry=0
Call Normalize ( FirstFloat , SecondFloat )
Word1=Val(IntegerPart1)
Word2=Val(IntegerPart2)
if Word1<Word2 then="" SysString="FirstFloat" FirstFloat="SecondFloat" SecondFloat="SysString" SingFlag1="1" Call="" Normalize="" (="" FirstFloat="" ,="" SecondFloat="" )="" end="" if="" Word1="Val(DecimalPart1)" Word2="Val(DecimalPart2)" if="" Word1="">Word2 then
DecimalPart=[Word]Word1-Word2
End if
if Word1=Word2 then
DecimalPart=0
end if
if Word1<Word2 then="" DecimalPart="<span">[Word]Word1+10000-Word2
Carry=1
end if
Word1=Val(IntegerPart1)
Word2=Val(IntegerPart2)
if Word1>Word2 then
IntegerPart=[Word]Word1-Word2-Carry
SingFlag=0
end if
if Word1=Word2 then
if Carry=0 then
IntegerPart=0
SingFlag=0
else
Word1=Val(DecimalPart1)
Word2=Val(DecimalPart2)
IntegerPart = 0
DecimalPart=[Word]Word2-Word1
SingFlag=1
End if
End if
SubFloat=FloatToString (IntegerPart, DecimalPart)
for i=1 to 3
if Right(SubFloat,1)="0" then
SubFloat=Left(SubFloat, len(SubFloat)-1)
end if
next
if Right(SubFloat,1)="." then
SysString=SubFloat+"0"
SubFloat=SysString
end if
if SingFlag=1 or SingFlag1=1 then
SysString="-"+SubFloat
SubFloat=Left(SysString,10)
End if
End Function
A first attempt to handle decimal numbers in GCBasic. They work well in PIC18F2550 but should be tested in other MCUs. I hope to help some friends out there
Dim FirstFloat , SecondFloat , SysString , DecimalLength as String * 10
Dim IntegerPart1 , IntegerPart2 as String * 5
Dim DecimalPart1 , DecimalPart2 as String * 4
Dim DotSing as String * 1
Dim DecimalPart , IntegerPart as Word
Dim Multi1 , Multi2, Multi3 as Long
Dim SysStrDat as Byte
'Add two strings as Floating numbers and return the result as string
Function AddFloat (In FirstFloat(), In SecondFloat()) As String * 10 'Handle numbers up 65535.9999
Call Normalize ( FirstFloat() , SecondFloat())
DecimalPart=Val(DecimalPart1)
DecimalPart=DecimalPart+Val(DecimalPart2)
IntegerPart=Val(IntegerPart1)
IntegerPart=IntegerPart+Val(IntegerPart2)
DecimalLength=left(SysString , Len(DecimalPart1)+1)
if DecimalPart> Val(DecimalLength)-1 then
DecimalPart=DecimalPart % Val(DecimalLength)
IntegerPart=[Word]IntegerPart+1
End if
AddFloat = Str(IntegerPart) + DotSing
if DecimalPart<10 then SingLoc=3
if DecimalPart>=10 and DecimalPart<=99 then SingLoc=2
if DecimalPart>=100 and DecimalPart<=999 then SingLoc=1
if DecimalPart>=1000 then SingLoc=0
AddFloat=AddFloat+Right(SysString, SingLoc)
AddFloat = AddFloat + Str(DecimalPart)
for i=1 to 3
if Right(AddFloat,1)="0" then
AddFloat=Left(AddFloat, len(AddFloat)-1)
end if
next
End Function
'Multiply two strings as Floating numbers and return the result as string
Function MultiFloat ( In FirstFloat(), In SecondFloat()) As String * 10
DotSing="."
SingLoc=Instr(FirstFloat,DotSing)
IntegerPart1=Left(FirstFloat, SingLoc-1)
SingLoc=Instr(SecondFloat,DotSing)
IntegerPart2=Left(SecondFloat, SingLoc-1)
SingLoc=Len(FirstFloat)-Instr(FirstFloat,DotSing)
digit1=SingLoc
DecimalPart1=Right(FirstFloat, SingLoc )
SingLoc=Len(SecondFloat)-Instr(SecondFloat,DotSing)
digit2=SingLoc
DecimalPart2=Right(SecondFloat, SingLoc)
FirstFloat=IntegerPart1+DecimalPart1
SecondFloat=IntegerPart2+DecimalPart2
Multi1 = Val32(FirstFloat)
Multi2 = Val32(SecondFloat)
Multi3=Multi1Multi2
Multi1=1000000000
SysCharCount=0
Flag=0
For i=1 to 10
if Multi3>=Multi1 then
SysStrData = Multi3 / Multi1
Multi3 = Multi3- SysStrDataMulti1
SysCharCount += 1
SysString(SysCharCount) = SysStrData + 48
Flag=1
else
if Flag<>0 then
SysStrData=0
SysCharCount += 1
SysString(SysCharCount) = SysStrData + 48
end if
end if
Multi1=Multi1/10
Next
locate 0,0
print SysString
SysCharCount=len(SysString)
Do While SysString(SysCharCount)="0"
SysCharCount -=1
SysString(0)=SysCharCount
Loop
SingLoc=digit1+digit2
if SingLoc<SysCharCount then
MultiFloat=Left(SysString, SysCharCount-SingLoc)
MultiFloat=MultiFloat + "."
else
MultiFloat="0." + Mid("000000000",1,SingLoc-SysCharCount)
end if
MultiFloat=MultiFloat + Right(SysString, SingLoc)
End Function
'Converts a string to Long
Function Val32(SysInString as String) as Long
Val32=0
SysCharCount = SysInString(0)
For SysStringTemp = 1 to SysCharCount
SysStrData = SysInString(SysStringTemp)
Val32 = Val32 * 10 + SysStrData - 48
Next
end Function
'Converts two numbers in one string as Floating number
Function FloatToString (IntegerPart, DecimalPart) As String * 10
FloatToString = Str(IntegerPart) + "."
FloatToString = FloatToString + Str(DecimalPart)
end Function
'Extract the Integer part and the Decimal Part of Floating number in string
Sub StringToFloat ( In FirstFloat , Out IntegerPart , Out DecimalPart)
DotSing="."
SingLoc=Instr(FirstFloat,DotSing)
SecondFloat=Left(FirstFloat, SingLoc-1)
IntegerPart = Val(SecondFloat)
SingLoc=Len(FirstFloat)-Instr(FirstFloat,DotSing)
SecondFloat=Right(FirstFloat, SingLoc )
DecimalPart = Val(SecondFloat)
End Sub
Sub Normalize (FirstFloat() , SecondFloat())
DotSing="."
SysString="100000000"
SingLoc=Instr(FirstFloat,DotSing)
IntegerPart1=Left(FirstFloat, SingLoc-1)
SingLoc=Instr(SecondFloat,DotSing)
IntegerPart2=Left(SecondFloat, SingLoc-1)
SingLoc=Len(FirstFloat)-Instr(FirstFloat,DotSing)
DecimalPart1=Right(FirstFloat, SingLoc )
SingLoc=Len(SecondFloat)-Instr(SecondFloat,DotSing)
DecimalPart2=Right(SecondFloat, SingLoc)
if len(DecimalPart1)<=3 then
DecimalPart1=DecimalPart1+Right(SysString,4-len(DecimalPart1))
end if
if len(DecimalPart2)<=3 then
DecimalPart2=DecimalPart2+Right(SysString,4-len(DecimalPart2))
end if
End sub
My test program
'Chip Settings
#chip 18F2550, 8
#config FOSC_INTOSC_HS, WDT=OFF, LVP=OFF, MCLRE=OFF, BOR=OFF
'Includes
#include "float.h"
'Defines (Constants)
#define LCD_NO_RW
#define LCD_IO 4
#define LCD_RS PORTB.5
#define LCD_Enable PORTB.4
#define LCD_DB4 PORTB.3
#define LCD_DB5 PORTB.2
#define LCD_DB6 PORTB.1
#define LCD_DB7 PORTB.0
'Variables
Dim ab , ab1 , ab2, ab3 as string
Dim x1 , x2 , x3 , x4 as Word
'Handle numbers up 65535.9999
x1=238
x2=48 ' 238.48
x3=29
x4=6723 ' 29.6723
ab1= FloatToString ( x1 , x2 )
ab2= FloatToString ( x3 , x4)
ab3 = AddFloat ( ab1 , ab2 )
cls
locate 1,0
print ab3
wait 5 s
cls
ab2 = AddFloat ( ab3 , "20.34" )
locate 1,0
print ab2
locate 0,0
print IntegerPart1
locate 0, 5
print DecimalPart1
locate 0,11
print IntegerPart2
locate 1, 11
print DecimalPart2
wait 5 s
cls
locate 1,0
print ab2
Call StringToFloat ( ab2 , x1 , x2)
locate 0,0
print x1
locate 0, 10
print x2
wait 5 s
cls
ab2 = MultiFloat ("234.06" , "0.073")
locate 1, 0
print ab2
start:
goto start
Nice piece of work!
A lot of good work!!
Well done.
The SubFloat Function for Subtraction. Anobium please correct the << stirngs>> from the title because it "hits" my eye.
'Subtract two strings as Floating numbers and return the result as string
'FirstFloat is the minuend and SecondFloat is the subtrahend
Function SubFloat (In FirstFloat(), In SecondFloat()) As String * 10
SingFlag1=0
SingFlag=0
Carry=0
Call Normalize ( FirstFloat , SecondFloat )
Word1=Val(IntegerPart1)
Word2=Val(IntegerPart2)
if Word1<Word2 then="" SysString="FirstFloat" FirstFloat="SecondFloat" SecondFloat="SysString" SingFlag1="1" Call="" Normalize="" (="" FirstFloat="" ,="" SecondFloat="" )="" end="" if="" Word1="Val(DecimalPart1)" Word2="Val(DecimalPart2)" if="" Word1="">Word2 then
DecimalPart=[Word]Word1-Word2
End if
if Word1=Word2 then
DecimalPart=0
end if
if Word1<Word2 then="" DecimalPart="<span">[Word]Word1+10000-Word2 Carry=1 end if Word1=Val(IntegerPart1) Word2=Val(IntegerPart2) if Word1>Word2 then
IntegerPart=[Word]Word1-Word2-Carry
SingFlag=0
end if
if Word1=Word2 then
if Carry=0 then
IntegerPart=0
SingFlag=0
else
Word1=Val(DecimalPart1)
Word2=Val(DecimalPart2)
IntegerPart = 0
DecimalPart=[Word]Word2-Word1
SingFlag=1
End if
End if
SubFloat=FloatToString (IntegerPart, DecimalPart)
for i=1 to 3
if Right(SubFloat,1)="0" then
SubFloat=Left(SubFloat, len(SubFloat)-1)
end if
next
if Right(SubFloat,1)="." then
SysString=SubFloat+"0"
SubFloat=SysString
end if
if SingFlag=1 or SingFlag1=1 then
SysString="-"+SubFloat
SubFloat=Left(SysString,10)
End if
End Function
Last edit: Dimitris Katsaounis 2014-12-27
Hi Dimitris
Very usefull. Have noticed this when multiplying.
if MultiFloat ("0.3" , "0.3") answer 0.09
if MultiFloat ("0.3" , "0.30") answer 0.009
if MultiFloat ("0.30" , "0.30") answer 0.0009
appears to add incorrect zero's
Regards
Mike
I want to draw attention to this and converting c code examples.
No mention of this when I posted hard (decimal point) sums https://sourceforge.net/p/gcbasic/discussion/579125/thread/df78cd39/