Forum - MCS Electronics

Author Message
Paulvk

Joined: 28 Jul 2006
Posts: 1193
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 )
Arera

Joined: 23 Sep 2007
Posts: 375
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).
MWS

Joined: 22 Aug 2009
Posts: 1813

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.
laborratte

Joined: 27 Jul 2005
Posts: 262
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).
Paulvk

Joined: 28 Jul 2006
Posts: 1193
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
MWS

Joined: 22 Aug 2009
Posts: 1813

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
Paulvk

Joined: 28 Jul 2006
Posts: 1193
Location: SYDNEY

Posted: Tue Nov 24, 2015 10:21 am    Post subject:

Thank you MWS

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
MWS

Joined: 22 Aug 2009
Posts: 1813

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
Duval JP

Joined: 22 Jun 2004
Posts: 932
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
Paulvk

Joined: 28 Jul 2006
Posts: 1193
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.

 Code: Dim B as byte

Regards Paul
MWS

Joined: 22 Aug 2009
Posts: 1813

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

But the ASM can be wrapped with a regular call to a sub, this will make its use much cleaner, will see...
MWS

Joined: 22 Aug 2009
Posts: 1813

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.
Paulvk

Joined: 28 Jul 2006
Posts: 1193
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
albertsm

Joined: 09 Apr 2004
Posts: 5061
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
MWS

Joined: 22 Aug 2009
Posts: 1813

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
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT + 1 Hour Page 1 of 1

 Jump to: Select a forum BASCOM AVR/8051----------------BASCOM-AVRBASCOM-8051BASCOM-ARDUINOShare your working BASCOM-8051 code hereShare your working BASCOM-AVR code hereBASCOM BETA-SLA BASCOM Related----------------EASY TCP/IPAVR-DOSAR7212KokkeKat FAT-free SD card libBASCOM Project Blog Other Stuff----------------VariousPCB'sRoboticsNew WebSiteAnnouncementsAVR Archive----------------BASCOM-AVR ArchiveBASCOM-8051 ArchiveBASCOM-AVR Unsupported versionsEasy TCP/IP ArchiveBASCOM-EDB
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum