Float/Double error in Lua PPC macs
Archives Forums/BlitzMax Bug Reports/Float/Double error in Lua PPC macs
| ||
Maybe not the most important bugs (as I may be one of the few using PPC these days (my main system is Intel, but I have a subsystem in PPC)). Whenever you need to deal with numbers like Float and Double numbers, everything works fine in Intel based machines, so Intel Macs and Windows are fine, and Linux has not been tried, but I don't expect any trouble there at all either. But as soon as PPC is involved things go wrong when transferring double and float numbers between BlitzMax and Lua my means of the MaxLua module. If you accept variables of these types from Lua by means of function parameters in functions you registered in Lua none of the numbers come out as they are supposed to be. Integer numbers are fine. Now I haven't yet checked what will happen if you send numbers of the just named types from BlitzMax to Lua, but I expect it to be problematic too. Of course I could be a bit behind on Bmax version (1.42 is on my PPC mac). I did try this out with as well as 'pure PPC' compiler as with Brucey's Universal Binary compiler both with the same results. |
| ||
PPC and Intel processors use a different format to store numerical data, which leads to the unexpected results you're seeing if you don't take that difference into account. From the blitzmax manual: Endian format refers to the order multi-byte values are stored. For example, an integer is four bytes long, but in what order should each byte be stored? Low byte first or high byte first? This choice is generally dictated by the CPU. For example, Intel CPU's such as the pentium store multi-byte values 'low byte first' which is known as little endian. On the other hand, PowerPC CPU's store multi-byte values 'high byte first' which is known as big endian. Most of the time, you don't have to worry about endian issues. As long as the same endian format is being used to read and write data, there is no problem. However, endian issues do need to be taken into account when reading or writing binary files. For example, writing a binary file on a PC (which is little endian) and reading it back on a Mac (which is big endian) may produce odd results if the file contains multibyte values. Endian streams help solve this problem by modifying the behaviour of stream commands that read or write multi-byte values. These commands are: ReadShort, ReadInt, ReadLong, ReadFloat, ReadDouble, WriteShort, WriteInt, WriteLong, WriteFloat and WriteDouble. Functions: BigEndianStream and LittleEndianStream To make the powerPC use the same format as the PC, use LittleEndianStream to read/write the data and they should match. |
| ||
LittleEndianStream or BigEndianStream is (as far as my knowledge goes) only an issue when it comes to reading and writing files and since that is NOT what is happening here, the functions named here won't solve the problem. Let's put it this way. Make a type like this Type LOBJ Method Test(A:double) print A end method End Type LuaRegisterObject New LOBJ,"LuaObject" Then make it execute the next Lua script print(LuaObject.Test(100)) Any result could pop up here, but not the right one. When I replace the 'Double' type with 'Int' it will work, even when using numbers higher than 255. Cut short, this is not a streaming issue (if it was Little/BigEndianstream would help), but a direct communication error between Lua and BlitzMax. Still I do think that Endians could be the issue here. Last edited 2012 |
| ||
I had the impression that MaxLua was using strings to transfer numbers. In that case endianness shouldn't matter. You could test the endianness idea. The single precision floats 1.0 and 4.60060299e-041 have the same representation, but with byte order reversed. If endianness is the problem and one of these numbers is sent the other will be received. Last edited 2012 |
| ||
Strings? Hmmm, I guess MaxLua doesn't do that by default, but there is a "ToFloat()" and "ToDouble()" on strings? If so, I can easily get around this bug at least :) I'm not working on my PPC right now (and it'll take too much time to set it up right away), but tomorrow I have to use that thing anyway, so then I'll post up some code (my Blitz and Lua code) and show the PPC results, and of course I'll then test the same code out on my Intel Mac and show those results as well. :) |
| ||
Ok, investigation showed that it may not be MaxLua doing the evil here. The bug was discovered when I wrote APIs for Lua where SetScale was used accepting numbers from Lua to determine the scaling rate. SetOrigin was also used here. Both accepted a 'Double' number directly from a Lua Script and gave incorrect results which I could (in the SetOrigin case) fix by just accepting Ints. Anyway, the test program and script I used here showed the next results which does appear as they should be... BMax: Strict Type LO Method I(A:Int) Print "INT: "+A End Method Method F(A:Float) Print "FLOAT: "+A End Method Method D(A:Double) Print "DOUBLE: "+A End Method Method S(A:String) Print "STRING: "+A End Method End Type LuaRegisterObject New LO,"L" Global Src$ = LoadString("Bug.lua") Print "-- Script~n"+Src+"~n-- End Script ~n~n" Local class:TLuaClass=TLuaClass.Create( src ) Local instance:TLuaObject=TLuaObject.Create( class,Null ) Lua: for ak=0,1000,25.25 do print('LUA: '..ak) L.I(ak) L.D(ak) L.F(ak) L.S(ak) end Output: Building Bug Compiling:Bug.bmx Linking:Bug.debug_PPC Executing:Bug.debug_PPC -- Script for ak=0,1000,25.25 do print('LUA: '..ak) L.I(ak) L.D(ak) L.F(ak) L.S(ak) end -- End Script LUA: 0 INT: 0 DOUBLE: 0.0000000000000000 FLOAT: 0.00000000 STRING: 0 LUA: 25.25 INT: 25 DOUBLE: 25.250000000000000 FLOAT: 25.2500000 STRING: 25.25 LUA: 50.5 INT: 50 DOUBLE: 50.500000000000000 FLOAT: 50.5000000 STRING: 50.5 LUA: 75.75 INT: 75 DOUBLE: 75.750000000000000 FLOAT: 75.7500000 STRING: 75.75 LUA: 101 INT: 101 DOUBLE: 101.00000000000000 FLOAT: 101.000000 STRING: 101 LUA: 126.25 INT: 126 DOUBLE: 126.25000000000000 FLOAT: 126.250000 STRING: 126.25 LUA: 151.5 INT: 151 DOUBLE: 151.50000000000000 FLOAT: 151.500000 STRING: 151.5 LUA: 176.75 INT: 176 DOUBLE: 176.75000000000000 FLOAT: 176.750000 STRING: 176.75 LUA: 202 INT: 202 DOUBLE: 202.00000000000000 FLOAT: 202.000000 STRING: 202 LUA: 227.25 INT: 227 DOUBLE: 227.25000000000000 FLOAT: 227.250000 STRING: 227.25 LUA: 252.5 INT: 252 DOUBLE: 252.50000000000000 FLOAT: 252.500000 STRING: 252.5 LUA: 277.75 INT: 277 DOUBLE: 277.75000000000000 FLOAT: 277.750000 STRING: 277.75 LUA: 303 INT: 303 DOUBLE: 303.00000000000000 FLOAT: 303.000000 STRING: 303 LUA: 328.25 INT: 328 DOUBLE: 328.25000000000000 FLOAT: 328.250000 STRING: 328.25 LUA: 353.5 INT: 353 DOUBLE: 353.50000000000000 FLOAT: 353.500000 STRING: 353.5 LUA: 378.75 INT: 378 DOUBLE: 378.75000000000000 FLOAT: 378.750000 STRING: 378.75 LUA: 404 INT: 404 DOUBLE: 404.00000000000000 FLOAT: 404.000000 STRING: 404 LUA: 429.25 INT: 429 DOUBLE: 429.25000000000000 FLOAT: 429.250000 STRING: 429.25 LUA: 454.5 INT: 454 DOUBLE: 454.50000000000000 FLOAT: 454.500000 STRING: 454.5 LUA: 479.75 INT: 479 DOUBLE: 479.75000000000000 FLOAT: 479.750000 STRING: 479.75 LUA: 505 INT: 505 DOUBLE: 505.00000000000000 FLOAT: 505.000000 STRING: 505 LUA: 530.25 INT: 530 DOUBLE: 530.25000000000000 FLOAT: 530.250000 STRING: 530.25 LUA: 555.5 INT: 555 DOUBLE: 555.50000000000000 FLOAT: 555.500000 STRING: 555.5 LUA: 580.75 INT: 580 DOUBLE: 580.75000000000000 FLOAT: 580.750000 STRING: 580.75 LUA: 606 INT: 606 DOUBLE: 606.00000000000000 FLOAT: 606.000000 STRING: 606 LUA: 631.25 INT: 631 DOUBLE: 631.25000000000000 FLOAT: 631.250000 STRING: 631.25 LUA: 656.5 INT: 656 DOUBLE: 656.50000000000000 FLOAT: 656.500000 STRING: 656.5 LUA: 681.75 INT: 681 DOUBLE: 681.75000000000000 FLOAT: 681.750000 STRING: 681.75 LUA: 707 INT: 707 DOUBLE: 707.00000000000000 FLOAT: 707.000000 STRING: 707 LUA: 732.25 INT: 732 DOUBLE: 732.25000000000000 FLOAT: 732.250000 STRING: 732.25 LUA: 757.5 INT: 757 DOUBLE: 757.50000000000000 FLOAT: 757.500000 STRING: 757.5 LUA: 782.75 INT: 782 DOUBLE: 782.75000000000000 FLOAT: 782.750000 STRING: 782.75 LUA: 808 INT: 808 DOUBLE: 808.00000000000000 FLOAT: 808.000000 STRING: 808 LUA: 833.25 INT: 833 DOUBLE: 833.25000000000000 FLOAT: 833.250000 STRING: 833.25 LUA: 858.5 INT: 858 DOUBLE: 858.50000000000000 FLOAT: 858.500000 STRING: 858.5 LUA: 883.75 INT: 883 DOUBLE: 883.75000000000000 FLOAT: 883.750000 STRING: 883.75 LUA: 909 INT: 909 DOUBLE: 909.00000000000000 FLOAT: 909.000000 STRING: 909 LUA: 934.25 INT: 934 DOUBLE: 934.25000000000000 FLOAT: 934.250000 STRING: 934.25 LUA: 959.5 INT: 959 DOUBLE: 959.50000000000000 FLOAT: 959.500000 STRING: 959.5 LUA: 984.75 INT: 984 DOUBLE: 984.75000000000000 FLOAT: 984.750000 STRING: 984.75 Process complete The project in which the bugging happens is too complex to post up here, so I'll need to make some sample code resembling this bug later. |