View previous topic :: View next topic |
Author |
Message |
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Mon Nov 23, 2015 12:44 pm Post subject: Why does double come out wrong in HEX |
|
|
Why is this double printing as BFF0000000000000
Regards Paul
Code: |
$regfile = "m168pdef.dat"
$crystal = 8000000
$baud = 9600
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 'default use 10 for the SW stack
$framesize = 100 'default use 40 for the frame space
Dim Wx As Double
Wx = &HFFFFFFFFFFFFFFFF
Print "Wx= " ; Hex(wx)
End
|
(BASCOM-AVR version : 2.0.7.8 ) |
|
Back to top |
|
|
Arera
Joined: 23 Sep 2007 Posts: 386 Location: Wuppertal, Germany
|
Posted: Mon Nov 23, 2015 5:22 pm Post subject: |
|
|
From the HELP (Fundamentals):
Double: 8 Bytes; 5.0 x 10^–324 to 1.7 x 10^308; Doubles are stored as signed 64 bit binary numbers
in short words: assigning FFF... all over a double does not represent the content of the straight value of all the FFFFs. Some of the Fs control the exponent and who knowes what else.
That is different to e.g. a byte or a word.
To find out more I'd suggest to google a bit, for it's a complex thing..... (at least to me). |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Mon Nov 23, 2015 5:37 pm Post subject: Re: Why does double come out wrong in HEX |
|
|
Paulvk wrote: | Why is this double printing as BFF0000000000000 |
If you would tell, what you'd expect, it will tell me about your understanding of internal representation of Singles and Doubles, i.e. mantissa, exponent and value range without rounding errors.
Hex is used for exact integer representation, how should it represent a float, means how would you tell the decimal place value?
It's not possible, so instead Hex() outputs the float's memory representation.
So why try this nonsense? Means I can tell PI is 3.141592653589 and if I scale it by 1E18, I can make 3141592653589793238 and thus &hB3FBCABC55F6E260 out of it.
But why in the world should I?
Your true reason behind this may be something different, so better describe, what you want to achieve. |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Mon Nov 23, 2015 7:38 pm Post subject: |
|
|
The compiler is interpreting your hex number in "Wx = &HFFFFFFFFFFFFFFFF " as int64, so it means "Wx = -1". And "BFF0000000000000" is, as MWS pointed out, the memory representation of -1 for floating point type DOUBLE.
&HFFFF and &HFFFFFFFF would also be interpreted as -1 (integer and long). |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Tue Nov 24, 2015 8:50 am Post subject: |
|
|
Hello all
I can now see what the compiler is doing it sees it as a number not setting the bits.
I needed to have a variable with 8 bytes to store the 1wire address of devices.
I then need to test 8 bytes of eeprom to see if all bits are all set to "1" new unused.
I want to do it in one step all 8 bytes at once not in a loop.
I have been able to compare the addresses of device and that stored in eeprom in one step using the double.
I can now set the bits to "1" (see below) it works but maybe not best practice I do not know.
Regards Paul
Code: |
$regfile = "m168pdef.dat"
$crystal = 8000000
$baud = 9600
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 'default use 10 for the SW stack
$framesize = 100 'default use 40 for the frame space
Dim X As Byte
Dim Wx As Double
Wx = 0
Dim Bx(2) As Long At Wx Overlay
For X = 1 To 2
Toggle Bx(x)
Next
Print "Wx= " ; Hex(wx)
End
|
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Tue Nov 24, 2015 9:57 am Post subject: |
|
|
Paulvk wrote: | I can now set the bits to "1" (see below) it works but maybe not best practice I do not know. |
The approach of using a double is dangerous, in case you forget one time, how floats are handled internally.
If you want to use it your way, I'd suggest to use a byte array as container and overlay it with longs.
Alternatively you may try out this:
Code: | $Regfile = "m328pdef.dat"
$Crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32
Const byte_to_comp = 8 ' bytes to compare
Dim val_A(8) As Byte ' value 1
Dim val_B(8) As Byte ' value 2
' val_A(2) = 1 ' test it
loadadr val_A , X
loadadr val_B , Z
!CLR R6 ' use predefined Err in register R6 as result
!LDI R19, byte_to_comp ' R19 as counter
!cmp_start:
!LD R20, X+ ' X points to val_A
!LD R21, Z+ ' Z points to val_B
!CP R20, R21 ' compare!
!BREQ cmp_equ ' if equal all ok, next
!LDI R19, 2^2 ' bitpos 2 in R6 is Err bit
!MOV R6, R19 ' set Err
!LDI R19, 1 ' exit at next loop
!cmp_equ:
!DEC R19 ' decrease loop counter
!BRNE cmp_start ' if not zero do another loop
If Err > 0 Then
Print "We have a miss"
Else
Print "We got a match"
End If
End |
As no compare-function exists in Bascom, I suggest to add one.
Last edited by MWS on Tue Nov 24, 2015 1:14 pm; edited 2 times in total |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Tue Nov 24, 2015 10:21 am Post subject: |
|
|
Thank you MWS
Maybe an addition to bascom.
Can the byte_to_comp be a variable?
Bit confused here with the Y+ is that correct?
Code: |
!LD R20, X+ ' X points to val_A
!LD R21, Y+ ' Z points to val_B
|
Regards Paul |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Tue Nov 24, 2015 1:13 pm Post subject: |
|
|
Paulvk wrote: | Bit confused here with the Y+ is that correct? |
No, was a typo, Y is in use by Bascom, by coincidence it did not hurt the simulation.
Quote: | Can the byte_to_comp be a variable? |
Yes, but then you have to provide this variable, you can't alternatively use Const then.
Code: | 'Const byte_to_comp = 8 ' bytes to compare
Dim byte_to_comp As Byte ' bytes to compare
byte_to_comp = 8
'!LDI R19, byte_to_comp ' R19 as counter
!LDS R19, {byte_to_comp} ' R19 as counter |
|
|
Back to top |
|
|
Duval JP
Joined: 22 Jun 2004 Posts: 1161 Location: France
|
Posted: Tue Nov 24, 2015 5:47 pm Post subject: |
|
|
I played with the windows calculator, it give the same result: -1
jp |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Wed Nov 25, 2015 12:09 am Post subject: |
|
|
Hello MWS
Can the byte_to_comp be a variable a bascom variable eg
How to put variable B into R19
This will make it a re-usable function so bascom gets a compare function.
Regards Paul |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Nov 25, 2015 3:55 am Post subject: |
|
|
Paulvk wrote: | Can the byte_to_comp be a variable a bascom variable eg
How to put variable B into R19 |
I've answered that already.
But the ASM can be wrapped with a regular call to a sub, this will make its use much cleaner, will see... |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Nov 25, 2015 12:17 pm Post subject: |
|
|
Here you are, ASM wrapped in a reusable function:
Code: | $Regfile = "m328pdef.dat"
$Crystal = 16000000
$hwstack = 40
$swstack = 32
$framesize = 32
Declare Function Compare(Val1 As Byte , Val2 As Byte , ByVal BtComp As Word) As Word
' purpose: byte-wise compare
' arg Val1: first value to compare, type = don't care
' arg Val2: second value to compare, type = don't care
' arg BtComp: count of bytes to compare, can be a constant or a variable
' range is 1 to 65535 bytes
' result: zero if all bytes within range of BtComp are matching
' 1 up to BtComp if there's a miss,
' zero is used for signaling a comlete match, so Config Base has no effect
' 1 is always the first byte of the variable, whatever type of variable it is
'### TEST BEGIN ###################################################################
Const testver = 0 ' edit for different tests
Dim mmpos As Word ' dimension word var to hold the result, i.e. mismatch position
Dim btt As Word ' bytes to test
#IF testver = 0
Dim val_A(8) As Byte ' byte array vs. byte array
Dim val_B(8) As Byte ' arrays are initialyzed 0
btt = 8
val_A(4) = 1 ' test it
#ENDIF
#IF testver = 1
Dim val_A As Double ' Double vs. byte array
Dim val_B(8) As Byte
btt = 8
val_B(2) = 1 ' test it
#ENDIF
#IF testver = 2 ' compare strings
Dim val_A As String * 16
Dim val_B As String * 16
btt = 12
val_A = "Hello Bascom"
val_B = "Hello Bascon" ' find the mismatch
#ENDIF
mmpos = Compare(val_A , val_B , btt)
If mmpos > 0 Then
Print "We have a miss at pos: " ; mmpos
Else
Print "Match!"
End If
'### TEST END ###################################################################
End
Function Compare(Val1 As Byte , Val2 As Byte , ByVal BtComp As Word) As Word
!LD XL, Y+0 ' get pointer to BtComp
!LD XH, Y+1
!LD R24, X+ ' R24/25 as counter
!LD R25, X
!MOVW R16, R24 ' save BtComp for later calculation of mismatch position
!LD XL, Y+4 ' get pointer to Val1 into X
!LD XH, Y+5
!LD ZL, Y+2 ' get pointer to Val2 into Z
!LD ZH, Y+3
!cmp_start:
!LD R20, X+ ' X points to Val1
!LD R21, Z+ ' Z points to Val2
!CP R20, R21 ' compare!
!BRNE cmp_nomatch ' if equal: ok, next one
!SBIW R24, 1 ' decrease loop counter
!BRNE cmp_start ' if not zero do another turn
!RJMP cmp_end
!cmp_nomatch:
!SBIW R24, 1 ' else: calculate the position of compare mismatch
!SUB R16, R24
!SBC R17, R25
!MOVW R24, R16
!cmp_end:
!LD XL, Y+6
!LD XH, Y+7
!ST X+, R24 ' store success or position of mismatch
!ST X, R25
End Function |
Edit: Reordered the inner loop, saves 1 cycle per turn, that's 8% for one turn, which would sum up to 1000 cycles for an array of 1000 Bytes. |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Thu Nov 26, 2015 10:24 am Post subject: |
|
|
Thank you MWS
This makes a nice addition to bascom
If I could write ASM I would write many libs like the LCD Guru.
But I am still learning to use bascom.
Maybe Mark will put it into the examples and list it in the help
Regards Paul |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Thu Nov 26, 2015 3:51 pm Post subject: |
|
|
hi MWS,
well done. i can see the value of this function so i will include it in a future version. _________________ Mark |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Nov 26, 2015 5:01 pm Post subject: |
|
|
albertsm wrote: | i can see the value of this function so i will include it in a future version. |
Nice to hear |
|
Back to top |
|
|
|