Issue 31001 - Currency variables do not properly assign to some values. Even CCur has problems.
Currency variables do not properly assign to some values. Even CCur has probl...
 Status: ACCEPTED None App Dev Unclassified api (show other issues) 3.3.0 or older (OOo) All All P3 Trivial --- AOO issues mailing list oooqa

 Reported: 2004-07-01 23:18 UTC by andrew 2017-05-20 11:27 UTC (History) 4 users (show) christianjunker issues joerg.skottke marcelly.bernard DEFECT --- ---

Attachments

 Note You need to log in before you can comment on or make changes to this issue.
 andrew 2004-07-01 23:18:35 UTC ```Problem: [code] Sub BadCurrency Dim c As Currency Dim d As Double d = 200.432 c = d Print c ' 200.4319 Print CCur(d) ' 200.4319 End Sub [/code] This should show 200.4320 when it is printed. I am certain that the problem is because the value is converted to a double precision number before it is converted to a currency value. [code] Dim c As Currency c = 200.432 Print c ' 200.4319 [/code] A currency variable acts like an integer. The currency type is a fixed precision floating point number that uses four decimal digits of precision. The problem is with the conversion from a double to the internal INT64. First, the constant is converted to a Double, and then it is converted to the INT64. The trouble starts with the file svtools/source/sbx/sbxconv.hxx [code]inline SbxINT64 ImpDoubleToCurrency( double d ) { return ImpDoubleToINT64( d * CURRENCY_FACTOR ); } [/code] The implementation of this routine, is as follows: [code] SbxINT64 ImpDoubleToINT64( double d ) { SbxINT64 nRes; nRes.Set( d ); return nRes; } [/code] Great, so now I know that it has to do with the Set method! See svtools/inc/sbxvar.hxx [code] void Set(double n) { if( n >= 0 ) { nHigh = (INT32)(n / (double)4294967296.0); nLow = (UINT32)(n - ((double)nHigh * (double)4294967296.0)); } else { nHigh = (INT32)(-n / (double)4294967296.0); nLow = (UINT32)(-n - ((double)nHigh * (double)4294967296.0)); CHS(); } } [/code] Our number is small, so nHigh is set to zero. nLow is equivalent to (UINT32)(n). I need to remind myself, because I have forgotten, exactly what the storage method is, and how the cast works, but I suspect that this is a bit operation more than anything, and it will simply take the appropriate bits. Unfortunately, the number in question, is probably not represented exactly, so if the bits are simply chopped off, then we lose the guard bits that would have allowed a double precision number to have appeared as though things were working nicely. I suppose that this is enough for now! Andrew Pitonyak``` andrew 2004-07-01 23:20:14 UTC ```You can see a pretty version of this error at the following location: http://www.oooforum.org/forum/viewtopic.php?p=38913#38913``` stephan.wunderlich 2004-07-06 14:24:08 UTC `SW->AB: Basic-runtime, looks like one for you` christianjunker 2005-08-07 20:41:30 UTC `still happens for 2.0 .` ab 2006-02-16 06:51:23 UTC ```Started ``` ab 2006-03-07 13:48:19 UTC ```ab: According to discussion with sw/kso -> 2.0.3 ``` ab 2006-04-28 12:24:34 UTC ```-> 2.0.4 ``` ab 2006-04-28 12:25:07 UTC ```Really -> 2.0.4 :-) ``` ab 2006-07-18 09:09:22 UTC ```-> 2.x due to code freeze and limited resources ``` ab 2006-08-21 14:09:03 UTC `-> 2.1` ab 2006-10-16 16:34:36 UTC ```According to discussion with mba/kso -> 2.2 as cws ab30 has to be integrated very soon. ``` ab 2007-01-02 14:15:32 UTC ```2.x due to limited resources. Has to be evaluated and targeted together with all other 2.x tasks. ``` ab 2007-11-16 13:25:51 UTC ```3.x due to limited resources ``` squenson 2008-07-16 20:53:31 UTC ```As published in the OOo User forum by lorenzo2 (http://user.services.openoffice.org/en/forum/viewtopic.php?f=45&t=7885&p=37054), the currency type is not properly handled in some basic math operations. There is an overflow after (2^31 - 1) / 10000. How to reproduce the bug ------------------------ 1. Create the following macro in an empty Calc document Sub Main Dim oSheet as object, oCell as object Dim cost as currency, total as currency Dim buy as integer oSheet=ThisComponent.Sheets.getByName("Sheet1") oCell=oSheet.getCellByPosition(0,0) 'A1 buy = oCell.getValue oCell=oSheet.getCellByPosition(1,0) 'B1 cost = oCell.getValue total = buy*cost oCell=oSheet.getCellByPosition(2,0) 'C1 oCell.setValue(total) End Sub 2. Now, if you set A1 to 5 and B1 to 40000 and execute the macro, cell C1 contains 200000, as expected. 3. If you now change B1 to 50000 and execute the macro again, C1 doesn't contain the expected value of 250000 - on my computer, it's now 38,252,449,584,978.1``` bmarcelly 2008-08-05 11:00:50 UTC ```Here is a more obvious example based on squenson comment. Dim A As Currency, B As Currency, R As Currency A = 4 B = 50000 R = A*B print "R=" & R ' result OK : 200000.0000 A = 5 R = A*B print "R=" & R ' Result example : 60686005228817.4336 The last result is variable, just like a random number generator. You have also wrong results with A = 4.3 for example. Tested on version 2.4.1. It's a pity that resolution of this report is systematically delayed.``` Marcus 2017-05-20 11:27:43 UTC `Reset assigne to the default "issues@openoffice.apache.org".`