ValD() StrD(X$,2) are killing me
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
ValD() StrD(X$,2) are killing me
OK is ther eany way to use this without rounding UP?
I have to keep the pricing in my database consistent with idiot pricing policy. People want you to pay 9.99 for something instead of 10.00...
I know... that extra penny would break you!
When I retrieve my prices from the database they have extra numbers past the decimal that aren't there in reality.
I had to change my program from my old way.
I have to use the CURRENCY value of those coluumns in the database or the reports in the database do not work.
the value is reported to the program as 9.9900 and not 9.99
the program calls it 10.00
I have to keep the pricing in my database consistent with idiot pricing policy. People want you to pay 9.99 for something instead of 10.00...
I know... that extra penny would break you!
When I retrieve my prices from the database they have extra numbers past the decimal that aren't there in reality.
I had to change my program from my old way.
I have to use the CURRENCY value of those coluumns in the database or the reports in the database do not work.
the value is reported to the program as 9.9900 and not 9.99
the program calls it 10.00
You are assigning it to a float aren't you?
Code: Select all
b.s="9.9900"
a.d=ValD(b)
Debug StrD(a,2)
c=ValD(b)
Debug StrD(c,2)
Vald means violence (!): http://www.dokpro.uio.no/perl/ordboksoe ... n&renset=jValD() StrD(X$,2) are killing me
You shouldn't use floats/doubles for money (but it's a problem as you haven't got anything else!)
you could use the VB6 runtime DLL's, the one with decimal functions is oleaut32.dll or you could use DecNumber which has more functionallity, BTW, I translated some of the headers from DecNumber and tested the lib compiled with PellesC OK, I used the package from the GNU GCC compiler, as it's licence has the exception clause allowing you to static link the lib into your app without the app falling under the GPL license.
You could try this: http://www.purebasic.fr/english/viewtop ... 312#228312
I think the easiest way to deal with money is to input as a string, convert the input to the pounds or dollars times 100 + pence/cents. Work with that and then convert the output back by integer dividing for the pounds/dollars and the remainder for pence/cents. That way it is all integers and no spurious bits creep in.
Mike.
(I'm never going to catch up with the improvements to this program)
(I'm never going to catch up with the improvements to this program)
you would still have to keep track of the implied decimal point if you do any math operations and adjust them to keep the 2 decimals as you suggested
for example, let's say you have n = 1234 with 2 decimals (12.34)
if you multiply n*n as integers you have 1522756 (result is 152.2756)
similarly if you add two numbers and you have a carry over.
for example, let's say you have n = 1234 with 2 decimals (12.34)
if you multiply n*n as integers you have 1522756 (result is 152.2756)
similarly if you add two numbers and you have a carry over.
There are cases though were two values are multiplied, eg $11.25 * 0.1 for ten percent tax.citystate wrote:I can't think of an instance where you'd multiply two currency values together though
But you can track it, as jack pointed out.
I went through all this zillions of years ago with dos and QBasic. In the long run using reals is easier and pretty darn accurate. More accurate in some cases.
The tiny differentials need a humongous amount of calcs and huge values to become significant at the cents level.
Generally, the only time the values need to be trimmed or fixed are for display purposes, or for rounding fractions when you do something like the tax calc above. And you would need to round that anyhow.
Thus: 1125 x 10 ($11.25 * 0.10) = 11250 with 4 decimal places, eg 1.125
Now you make your rounding decision. Except you are using integers instead of floats and you are also having to keep track of decimal places.
Also, if you use integers, you will need to buffer for times when you divide. Otherwise bits fall off:
Code: Select all
vA.l = 1125
vB.l = 10
vC = vA / vB
Debug vC

I truly believe you are better off staying with doubles and just adjusting when it is absolutely necessary. I do believe that once you get into any * / math you are going to create greater inaccuracies with integers.
Dare2 cut down to size
-
- Enthusiast
- Posts: 480
- Joined: Thu Jul 27, 2006 4:06 am
Could you adapt it to something like this? (string based)
It's not as fast as handling floats but it'll be secure in comparison.
But, anyway what's wrong with this? It returns correctly here:
Code: Select all
Structure Money
bucks.l
cents.l
EndStructure
Macro MoneySetString(_handle_, _str_)
_handle_\bucks = Val(_str_)
_handle_\cents = Val(StringField(_str_,2, ","))
EndMacro
Macro MoneyGetString(_handle_)
Str(_handle_\bucks) + "," + Str(_handle_\cents)
EndMacro
;- Test
Define.Money test
MoneySetString(test, "89,99")
Debug MoneyGetString(test)
But, anyway what's wrong with this? It returns correctly here:
Code: Select all
money.f = 89.99
Debug StrF(money, 2)
The QBasic app I mentioned above handled lending portfolio's for financiers and small commercial banks. It passed all the legal requirements on a heavily governed industry. It used doubles (14 digits of accuracy, 15 sometimes claimed).
Admittedly, none of the users operated in the tens of billions, but it coped.
Doubles should be safe for a restaurant POS system and if the prices are that high that it cannot cope then I am not eating there!
In the absence of a currency type and good math to handle it, floating point seems safer than integer to me.
I can't see the actual problem here. However I am probably missing something so I stand to be corrected and educated.
Code: Select all
my.d = 123456789012.34
Debug my
Doubles should be safe for a restaurant POS system and if the prices are that high that it cannot cope then I am not eating there!

In the absence of a currency type and good math to handle it, floating point seems safer than integer to me.
I can't see the actual problem here. However I am probably missing something so I stand to be corrected and educated.

Dare2 cut down to size