Issue 76852 - Basic : incorrect conversions Single to String and Double to String
Summary: Basic : incorrect conversions Single to String and Double to String
Alias: None
Product: App Dev
Classification: Unclassified
Component: scripting (show other issues)
Version: 3.3.0 or older (OOo)
Hardware: All All
: P3 Trivial
Target Milestone: 4.0.0
Assignee: damjan
QA Contact: Unknown
Keywords: oooqa
Depends on:
Reported: 2007-05-02 13:28 UTC by bmarcelly
Modified: 2013-07-12 14:17 UTC (History)
6 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation in: 3.4.0
Developer Difficulty: ---

Call myftoa() with nExpWidth=4 even when nNum=dMaxNumWithoutExp (591 bytes, patch)
2012-10-30 18:59 UTC, damjan
orw: review+
Details | Diff

Note You need to log in before you can comment on or make changes to this issue.
Description bmarcelly 2007-05-02 13:28:43 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)
Comment 1 bmarcelly 2007-05-02 13:46:42 UTC
Found the same problem with Double:

dim d as double
d = 100000000000000
print d   ' display : 1
Comment 2 kay.ramme 2007-05-10 09:11:04 UTC
Sorry for the delay.

Andreas, could you please take care of this ... thanks.
Comment 3 ab 2007-05-14 12:10:19 UTC
Maybe a duplicate, but I could not find duplicate task at the first look
Comment 4 Martin Hollmichel 2007-12-07 12:13:23 UTC
set target to 3.x according to
Comment 5 cai_73077 2008-02-05 14:34:37 UTC
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 > Basic… 
3.On the 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! 
Comment 6 mikeadvo 2011-02-09 17:50:48 UTC
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.
Comment 7 mikeadvo 2011-02-09 20:32:02 UTC
But the bugs are still in 3.3 and 3.4 (m92) (.deb). So they seem to be platform

If you know them, workarounds are easy.

But they are nasty and seem easy to fix.
Comment 8 mechtilde 2011-02-09 20:50:17 UTC
change some flags
Comment 9 ab 2011-02-10 09:04:35 UTC
ab->mechthilde: What makes this issue P2 according
to the priority rules?
Comment 10 damjan 2012-10-30 04:29:31 UTC
Given this result:

Dim s as single
s = 1000000.0
print s                   ' displays 1
if s = 1000000.0 THEN
  print "it is 1000000.0" ' <---
  print "it's not 1000000.0"
if s = 1 THEN
  print "it is 1"
  print "it's not 1"      ' <---

it would seem that the print function is broken.
Comment 11 damjan 2012-10-30 18:59:12 UTC
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".
Comment 12 Oliver-Rainer Wittmann 2012-10-31 12:42:28 UTC
taking over to review the patch
Comment 13 Oliver-Rainer Wittmann 2012-11-01 08:16:30 UTC
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.
Comment 14 Oliver-Rainer Wittmann 2012-11-01 08:17:17 UTC
@damjan: I think it is up to you to commit the patch.
Comment 15 SVN Robot 2012-11-01 09:00:01 UTC
"damjan" committed SVN revision 1404506 into trunk:
#i76852#  Basic : incorrect conversions Single to String and Double to String...
Comment 16 damjan 2012-11-01 09:02:38 UTC
Thank you for your review Oliver. Commited. Resolving fixed.