bmx-ng / bcc

A next-generation bcc parser for BlitzMax
zlib License
33 stars 12 forks source link

Const x=2^1 ... vs variable x = 2 ^ integerVariable #542

Closed GWRon closed 3 years ago

GWRon commented 3 years ago

Ok ... just found out the hard way, that my code is full of dumb decisions --- and maybe I also found a bug in bcc :)

        local flag:int = 0
        For local flagNumber:int = 0 to 7 'manual limitation to "7" to exclude series/paid?
            flag = 2^flagNumber
            'contains that flag?
            if dataFlags & flag > 0
                if result <> "" then result :+ " & "
                result :+ GetLocale("PROGRAMME_FLAG_" + TVTProgrammeDataFlag.GetAsString(flag))
            endif
        Next

so the idea was, to iterate over 1,2,4,8,16,...

While it worked on my computer and on others, it failed for a user - and on my windows 10 notebook. So why? flag is an integer. the ^ operator .... returns a double ... so "integer variable stores result of 2^flagNumber". This results on my computer in "flag = 16.0000003" (for 2^4) - but on the users computer it was "flag = 15.9999997". Casting this to integer ... results in either "flag becoming 16" or "flag becoming 15"

Of course this lead to totally different results :+1:

Ok ... so far to my stupidness - but why is this an issue here?

In other files I have stuff like this:

Const GUI_OBJECT_DRAGGED:Int                    = 2^0
Const GUI_OBJECT_VISIBLE:Int                    = 2^1
Const GUI_OBJECT_ENABLED:Int                    = 2^2
Const GUI_OBJECT_CLICKABLE:Int                  = 2^3
Const GUI_OBJECT_DRAGABLE:Int                   = 2^4
Const GUI_OBJECT_MANAGED:Int                    = 2^5
Const GUI_OBJECT_POSITIONABSOLUTE:Int           = 2^6
Const GUI_OBJECT_IGNORE_POSITIONMODIFIERS:Int   = 2^7
Const GUI_OBJECT_IGNORE_PARENTPADDING:Int       = 2^8
Const GUI_OBJECT_IGNORE_PARENTLIMITS:Int        = 2^9
Const GUI_OBJECT_ACCEPTS_DROP:Int               = 2^10
Const GUI_OBJECT_CAN_RECEIVE_KEYSTROKES:Int     = 2^11
Const GUI_OBJECT_CAN_GAIN_FOCUS:Int             = 2^12
Const GUI_OBJECT_DRAWMODE_GHOST:Int             = 2^13

constant expressions (2 + 4 .... or 2^5) are already evaluated during compilation. These constants are placed in the ".i"-files in "/.bmx". In the case of the constants they are all "correct" like a "integer power-of" calculation.

This is because there it decides to use bbLongPow.

The code above --- results in: bbt_flag=((BBINT)bbFloatPow(2.0000000000000000, ((BBDOUBLE)bbt_flagNumber)));

Why ? Isn't any number without a "dot" by default an integer?


TL;DR The code

Local x:int
For local i:int = 0 to 5
  x = 2 ^ i
  print x
Next

should use bbLongPow, not bbFloatPow ...somehow BCC assumes that this expression contains floats.

GWRon commented 3 years ago

Example:

SuperStrict
Framework Brl.StandardIO

Local x:Int
For Local i:Int = 0 To 8
  x = 2 ^ i
  Print "2 ^ " + i + " = " + x
Next

Windows 10 Laptop:

2 ^ 0 = 1
2 ^ 1 = 1
2 ^ 2 = 3
2 ^ 3 = 7
2 ^ 4 = 15
2 ^ 5 = 31
2 ^ 6 = 63
2 ^ 7 = 127
2 ^ 8 = 255

Edit: and my linux box:

2 ^ 0 = 1
2 ^ 1 = 2
2 ^ 2 = 4
2 ^ 3 = 8
2 ^ 4 = 16
2 ^ 5 = 32
2 ^ 6 = 64
2 ^ 7 = 128
2 ^ 8 = 256
Kerntrick commented 3 years ago

Interesting. I use a slightly older bcc and don't have this bug on windows. bbt_x=((BBINT)bbLongPow(2LL, ((BBLONG)bbt_i)));

GWRon commented 3 years ago

@Kerntrick https://github.com/bmx-ng/bcc/commit/d6b0fed998a429c1996b6c57360471005ed2cb13 added it - and this commit is dated september 2019.

So your bcc must be not just "slightly older" :)

@woollybah That was quite a really quick fix. Thanks.