deltarho, nice summary of the problem, very well put. Yes, fb's generators are using ulong with the last step to divide the ulong by 2^32 to return a double. Can get back the exact ulong value with rnd()*cdbl(4294967296ull); not so appealing if you want the fastest.
Re SHL 32, etc. thank you for taking time to explain. wiki page
Coercion and Conversion is supposed to help, but it is missing a few things. I see. SHIFT is a statement in PB. And SHL is binary operator in FB.
A few more details, to add to your info and MrSwiss info:
1)
variable = expression, the expression is fully evaluated, then assigned (stored) to the variable.
2) fbc automatically coerces types, most commonly from a type that is smaller than the machine register size up to the machine register size (32/64bit depending on target), otherwise programmer would be required to explicitly convert everything to compatible types. Coercion is different depending on target 32/64bit.
3) expr SHL N
- expr gets loaded to a machine register 32bit or 64bit, depends on fbc target
- SHL 32, shifts the machine register, warning on 32bit. On 64bit, it's fine
- on 64bit, we would get a warning on SHL 64, or higher
- at least
SHL Page warns us that the results are undefined if N is negative or more than bits in the register.
- FYI, the undefined behavior under the hood is that, fbc translates to expr SHL (N MOD BITS), where bits is 32 or 64, depends on fbc target.
4) Can use C### conversions where ever needed because fbc optimizes them away, if there is no change in data type size.
5) This code is the minimum that makes sense for both 32/64bit with result in 64bit variable:
Code: Select all
dim as ulong n1, n2
Dim As ulongint res = (culongint(n1) Shl 32) + n2
FYI
My speed timings, probably a little slow because I am running an un-optimized debug version of fb's rtlib:
Code: Select all
fbc -gen gas -target win32
TwoUlongsToDouble: 0.4999107723015807 1.476572121705772
TwoUlongsToDouble32: 0.5000478563958972 1.422788166046075
TwoUlongsToDouble64: 0.4999743510336273 1.452752335902858
fbc -gen gcc -target win64
TwoUlongsToDouble: 0.4999608822256317 2.615885008126497
TwoUlongsToDouble32: 0.4997475645844072 2.571060933754779
TwoUlongsToDouble64: 0.4999529535941112 2.547443617833778