Apache OpenOffice (AOO) Bugzilla – Issue 76852
Basic : incorrect conversions Single to String and Double to String
Last modified: 2017-05-20 09:31:58 UTC
Run this Basic macro: Dim s as single s = 999999 print s ' display : 999999 s = s+1 print s ' display : 1 ***** incorrect *** s = s+1 print s ' display : 1.000001E6 Same error with this: Dim s as single s = 1000000 print CStr(s)
Found the same problem with Double: dim d as double d = 100000000000000 print d ' display : 1
Sorry for the delay. Andreas, could you please take care of this ... thanks.
STARTED, OOo 2.x Maybe a duplicate, but I could not find duplicate task at the first look
set target to 3.x according to http://wiki.services.openoffice.org/wiki/Target_3x
The defect is reproduced on OOo V2.3.1 Intel Windows XP, Service Pack II. 1.Start up OOo writer 2.Click on Tools > Marcros > Organize Marcros > OpenOffice.org Basic… 3.On the OpenOffice.org Basic Macros window, expend My Macros, and click on New to get to the OOo Basic programming environment 4.In the body of the main subroutine of the sample code generated, insert the following test cases. Dim s as single s = 999999 print s ' display: 999999 correct (1) s = s+1 print s ' display: 1 incorrect (2) s = s+1 print s ' display : 1.000001E+6 correct (3) Dim x as single x = 1000000 print CStr(x)' display : 1 incorrect (4) Dim d as double d = 1000000000000000 print d ' display : 1E+15 correct (5) 5. On the tool bar, click compile and then run, if no errors. Test case (5) is actually correct in my testing environment. (OOo V2.3.1 on WinXP SP2). Looks like there’s problem with the number one million (1,000,000). It may be to do with a single type upper bound handling. More test cases has been conducted, and these are the results I found: Dim x1 as single x1 = 999999 print CStr(x1)' display : 999999 correct (6) x1 = 1000001 print CStr(x1)' display : 1.000001E+6 correct (7) Dim d1 as double d1 = 1000000 print d ' display : 1000000 correct (8) d1 = 100000000000000 print d ' display : 1 incorrect (9) The double type boundary is having the similar problem, as in test case (9). The value 100,000,000,000,000 is also displayed incorrectly!
Sub Main Dim s as double s = 1000000 print CStr(s) End Sub works for me in 3.2.1 (.deb), "Dim s as long" too.
But the bugs are still in 3.3 and 3.4 (m92) (.deb). So they seem to be platform independent. If you know them, workarounds are easy. But they are nasty and seem easy to fix.
change some flags
ab->mechthilde: What makes this issue P2 according to the priority rules?
Given this result: Dim s as single s = 1000000.0 print s ' displays 1 if s = 1000000.0 THEN print "it is 1000000.0" ' <--- else print "it's not 1000000.0" endif if s = 1 THEN print "it is 1" else print "it's not 1" ' <--- endif it would seem that the print function is broken.
Created attachment 79839 [details] Call myftoa() with nExpWidth=4 even when nNum=dMaxNumWithoutExp Here's a possible patch. The problem happens as follows: print is compiled by SbiParser::Print() in main/basic/source/comp/io.cxx to _PRINTF or such. Somehow SbiRuntime::StepPRINTF() in main/basic/source/runtime/step0.cxx then gets called and executes p->GetString() where p is SbxVariableRef. SbxValue::GetString() in main/basic/source/sbx/sbxvalue.cxx is called. SbxValue::Get() in the same file is called. ImpGetString() in main/basic/source/sbx/sbxstr.cxx is called. ImpPutSingle() in main/basic/source/sbx/sbxsng.cxx case SbxSTRING is then called, and it passes a length of 6 to ImpCvtNum() as its nPrec parameter. ImpCvtNum() in file sbxscan.cxx defines dMaxNumWithoutExp to be 1E6 if nPrec is 6, and 1E14 otherwise. It calls myftoa(), which returns "1000000" (this is unusual - it normally returns a decimal separator, eg. "999999.0" for 999999 and "1.000001E6" for 1000001). Then ImpCvtNum() corrupts this string, because it expects to stop at "E" or at the end of the string, then peel off previous trailing zeroes until it hits the decimal separator or another digit or has peeled off nPrec (6) digits. However "1000000" has no decimal separator and no non-zero digit, causing it to peel off the positive powers of 10 (!!!!!!!!!!) leaving only "1". There is 2 ways to fix the problem: * somehow patch myftoa() to return something like "1.000000E6" instead of "1000000" * patch ImpCvtNum() to call myftoa() with an nExpWidth of 4 even when nNum is equal to dMaxNumWithoutExp My patch takes the latter approach. With it "1E6" is printed instead of "1".
taking over to review the patch
Comment on attachment 79839 [details] Call myftoa() with nExpWidth=4 even when nNum=dMaxNumWithoutExp conclusion on the analysis makes sense from my point of view. Thus, patch looks good and solves the problem.
@damjan: I think it is up to you to commit the patch.
"damjan" committed SVN revision 1404506 into trunk: #i76852# Basic : incorrect conversions Single to String and Double to String...
Thank you for your review Oliver. Commited. Resolving fixed.