Format difference in Mac and Windows

Put this in the open event of an app then run in Mac and Windows:

dim d as Double = 10.5 MsgBox Format(d, ",0.00") + EndOfLine + Format(d, ",#")

Results Mac:

Results Windows:

What? Are the rounding rules really different for Mac and Windows?

I would call this a bug…

I wonder if they are using platform specific code in Format under the hood …

if so and the rounding IS different because of it, that is one HUGE reason NOT to use platform specific code for non UI stuff for an X-Platform product!

Lots of subtle bugs could be introduced because of those types of things!

BTW try 11.5 on both platforms to see if one is following the even-odd rounding rules or both behave the same way with an odd number.

  • karen




It looks like Mac is using bankers rounding (round 0.5 to the nearest even integer). Of course, more test needed to be sure.

I frankly don’t care what kind of rounding is used as long it is consistent across platforms. As a developer of accounting software it’s incredibly embarrassing to have to face my clients on something so basic.

I wonder if this is something in the C libraries on each platform
I cant say which functions might be in use for the format function but you might try sprintf or snprintf on each and see if that results in a similar difference

Either way it should be reported as an inconsistency across platforms that maybe Xojo can fix

a double of 10.5 looks like this
i would print the real values first.

Richard, for accounting software maybe is better to use Currency or try Bob Delaney’s Decimal plugin

[quote=471677:@Markus Rauch]a double of 10.5 looks like this
i would print the real values first.[/quote]
fwiw 10.5 IS a double that can have an exact representation since the .5 is a precise power of 2 (lots arent)

10 = 2^2 + 2^1
.5 = 1/(2^1)

in this case 10.5 can be precisely represented in a IEEE 754 double without the normal error


or just scale an int64 (which is what VB did for its currency type)

a quick test in Xcode and VS suggests this may be down to C runtime differences
I get different results in Xcode and VS with this

double d = 10.5 ;
char buffer[20] ;
snprintf(buffer, 20, "%8.2F", d) ; 
// whats in buffer now ?
snprintf(buffer, 20, "%8.0F", d) ; 
// whats in buffer now ?


wow xojo show me a real 10.50000000000 at windows :slight_smile: (unexpected)
i will look what my mac mini print.

really doesnt matter what Xojo prints
the conversion to a string form for printing could be subtly flawed resulting in what you saw
or the conversion from the literal to a double could be flawed again resulting in a subtle error

either way 10.5 is representable precisely in either a single or double floating point format

that we get very different rounding on a value that SHOULD be precisely representable is problematic as Richard pointed out in his prior post

This is true, but using the currency type, the result is the same. I believe that Xojo converts the currency type to double within the Format function.

Whatever the reason for this behavior, Xojo should fix it so that Format works consistently across platforms.

Richard I’m quite sure that IS the case

its why I recommended using a scaled Int64

rounding like this becomes a non-issue
and when you “print” you just turn the int64 into a string and insert the correct decimal marker at whatever position is needed (same for thousands if you need those)

for instance if you used an int64 and wanted 4 decimals then you would use str or format to get the integer as a string (no decimals)
and then insert a decimal point so you have 4 decimal places
conversion of user values to this type amounts to adding 0’s to pad out so you have 4 decimal places
you have to be careful of using VAL though as once it reaches certain values you start to lose low digits as doubles have a limited ranges that you start to exceed with really large values

[quote=471682:@Norman Palardy]
in this case 10.5 can be precisely represented in a IEEE 754 double without the normal error

MY BAD !!! this is the SINGLE format not double
a double is
0x4025000000000000 = 01000000 00100101 00000000 00000000 00000000 00000000 00000000 00000000

and the following code takes that binary and turns it into a double in xojo which is precise

Dim mb As New memoryblock(8)
mb.LittleEndian = False

' mb.doubleValue(0) = 10.5

mb.uint8value(0) = &b01000000
mb.uint8value(1) = &b00100101
mb.uint8value(2) = &b00000000
mb.uint8value(3) = &b00000000
mb.uint8value(4) = &b00000000
mb.uint8value(5) = &b00000000
mb.uint8value(6) = &b00000000
mb.uint8value(7) = &b00000000

Dim d As Double = mb.DoubleValue(0)