Page Index Toggle Pages: [1] 2  Send Topic Send Topic Print Print
Hot Topic (More than 10 Replies) Money Format (Read 4085 times)
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Money Format
Apr 1st, 2005 at 5:57pm
Print Post Print Post  
Mark,

I have some elements formatted for money that get their values from programming. Most of the time the value handed to the money element has more than 2 digits after the decimal.

Based on a previous discussion in the "MONEY VALUES ROUNDING" thread, I stopped using @Rnd because of it's unpredictable floating-point method of rounding money values. I changed over to using the OS method that you suggested which displays money predictably on the form.

The problem is the money fields are actually storing the values internally with 6 digits after the decimal point without rounding (which can be seen in Table View). This brings us back to using @Rnd (and it's unpredictable results) when getting a value from a money element.

Shouldn't money fields be storing data with only 2 decimal places, or at least storing the rounded value?

An example of when this is a problem would be when converting dollar amounts to words. Using the code in the latest programming guide on page 249, entering $1.3077 in the money element will produce "77/100" for the cents portion in the words element.
  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
The Cow
YaBB Administrator
*****
Offline



Posts: 2530
Joined: Nov 22nd, 2002
Re: Money Format
Reply #1 - Apr 1st, 2005 at 6:33pm
Print Post Print Post  
Money and all numeric fields are stored in IEEE binary format. Binary formats do not have any limit on decimal places beyond the physical limitations of being 64 bits. Truncation and rounding only take place when the number is formatted for display (turned into a string) or converted into an integer. That is why it is important that numbers be left unformatted and unconverted until the very last thing - displaying results.
  

Mark Lasersohn&&Programmer&&Lantica Software, LLC
Back to top
IP Logged
 
Bob_Hansen
Senior Member
Members
*****
Offline


WOW, They have the Internet
on computers now!

Posts: 1861
Location: Salem, NH
Joined: Nov 24th, 2002
Re: Money Format
Reply #2 - Apr 1st, 2005 at 6:49pm
Print Post Print Post  
Quote:
Truncation and rounding only take place when the number is formatted for display (turned into a string) or converted into an integer.
I think that you mean converted into an integer TYPE?

So, if a caluculation (vCalc) ends up as 1.3077, converting to an integer would result in 1. 

But having another variable, var vResult as Int, and doing vResult = vCalc we would end up with correct number. 
Now we would format vResult, is that correct?
  



Bob Hansen
Sesame Database Manager Professional
Sensible Solutions Inc.
Salem, NH
603-898-8223
Skype ID = sensiblesolutions
Back to top
IP Logged
 
The Cow
YaBB Administrator
*****
Offline



Posts: 2530
Joined: Nov 22nd, 2002
Re: Money Format
Reply #3 - Apr 1st, 2005 at 7:21pm
Print Post Print Post  
No, in no case can you put a double into an integer without a conversion and a possible loss of data, no matter how it is done. When mixing floating point numbers with integers you may get rounding, truncation, and out-of-range errors.

Mind you, none of this is unique to Sesame. No application can actually convert between doubles and integers without these side effects. Internally (on any 32 bit OS), integers are stored as 32 bit, base 2, numerics. Doubles are 64 bit IEEE, "floats" with sign, mantissa, and exponent. They cannot be mixed without conversion. On 64 bit OSs, the number of available bits doubles to 64 and 128 respectively.

Some applications get around this by making sure that integers are not available to end users. Q&A, for example, stores everything as a string, and converts to doubles (never integers) when doing math.

In general, in Sesame, if you are doing math that might ever result in a fractional portion, you are well advised to use doubles. Always use the type that is appropriate for the function or subroutine you are calling.
  

Mark Lasersohn&&Programmer&&Lantica Software, LLC
Back to top
IP Logged
 
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Re: Money Format
Reply #4 - Apr 1st, 2005 at 8:34pm
Print Post Print Post  
Mark,

So how can I read the final displayed value that appears on the screen (required for an accurate money to words conversion)? Or is that not possible, and I should take my chances with letting @Rnd trim the value before it is assigned to the money element so that it is stored as just 2 decimal places?
  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
The Cow
YaBB Administrator
*****
Offline



Posts: 2530
Joined: Nov 22nd, 2002
Re: Money Format
Reply #5 - Apr 1st, 2005 at 8:51pm
Print Post Print Post  
If you are using the SYSTEM format for the LE that it holding the money value, it will always be displayed as your system should display currency. That also means that any rounding or truncation that occurs will only occur at the last moment before display - reducing total innaccuracy. In other words, there is rarely any need to forcefully round a double, though you may choose to for the sake of table view and ASCII export (where data appears unformatted).
  

Mark Lasersohn&&Programmer&&Lantica Software, LLC
Back to top
IP Logged
 
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Re: Money Format
Reply #6 - Apr 1st, 2005 at 9:35pm
Print Post Print Post  
Thanks Mark.

I do want to use table view, so I guess I will need to go back to using @Rnd.
  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
The Cow
YaBB Administrator
*****
Offline



Posts: 2530
Joined: Nov 22nd, 2002
Re: Money Format
Reply #7 - Apr 1st, 2005 at 9:41pm
Print Post Print Post  
@Rnd shouldn't be a problem. It is using handwritten code as opposed to a MS library call. It should be perfectly predictable on double values.
  

Mark Lasersohn&&Programmer&&Lantica Software, LLC
Back to top
IP Logged
 
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Re: Money Format
Reply #8 - Apr 1st, 2005 at 9:56pm
Print Post Print Post  
Ohhh! I thought it was using the same floating-point method. That will solve my problem.

THANKS!
  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Re: Money Format
Reply #9 - Apr 1st, 2005 at 10:13pm
Print Post Print Post  
Now I know why I thought @Rnd was using the same floating-point method. The following is a quote from ray in the "MONEY VALUES ROUNDING" thread.

Quote:
Hello Carl,

@Rnd() does not always round up numbers ending in 5 either. For example @Rnd(8.895, 2) will round to 8.89. If you format the number element to System, and you have the default number format for the united states, 8.895 will round to 8.90

-Ray


Since @Rnd was handwritten, is this something that can be fixed?
  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
Hammer
YaBB Administrator
Lanticans
*****
Offline


Fire bad. Tree pretty.

Posts: 3436
Location: Ohio
Joined: Nov 22nd, 2002
Re: Money Format
Reply #10 - Apr 1st, 2005 at 11:23pm
Print Post Print Post  
We're considering doing so, but the issues are non-trivial.

Many, if not all, of the operating system functions are subject to rounding errors. A rewrite would involve bypassing the operating system functions. Doing it "just like Q&A" (which I assume is what you are looking for) is one method, but it doesn't fix the inherent inaccuracy. It simply changes it to a different brand of inaccuracy. Is the Q&A style inaccuracy "better" simply because it can be predicted? Maybe, maybe not.

It's really a question of in what way do we want to be inaccurate? The predictable way, or the way implemented by a standards organization who put a lot of thought into the effect of such unavoidable inaccuracy over the long run of repeated calculations? Do we want one record to round completely predicatably, or do we want 10000 records to round in a way that evens out the inaccuracy over the whole of the database?

We're looking into the possibilities.
  

- Hammer
The plural of anecdote is not data.
Back to top
IP Logged
 
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Re: Money Format
Reply #11 - Apr 1st, 2005 at 11:30pm
Print Post Print Post  
Being frustrated with this issue, I have written my own user-defined function to solve it. So far, it seems to be working flawlessly.

I would welcome any feedback from anyone who wants to try this out.

Place it in Global Code, of course.

Code
Select All
//########## Begin Custom Rounding Function ##########
Function @cuRnd(Value as double, Places as int)

Places = Places + 1

if @Mid(Value, @Instr(Value, ".") + Places, 1) >= 5
      Value = Value + 0.01

Value = @Del(Value, @Instr(Value, ".") + Places, 10)

Return value

End Function
//########## End Custom Rounding Function ########## 



EDIT: This code doesn't handle negative numbers properly. Please use the updated code in the posting below.
« Last Edit: Apr 2nd, 2005 at 12:58am by Carl Underwood »  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Re: Money Format
Reply #12 - Apr 1st, 2005 at 11:36pm
Print Post Print Post  
Erika,

I was only looking to have MONEY fields round up if the 3rd decimal place digit is a "5", not all calculations.

Anyway, I was composing my post when you posted your last one. I think I have found the perfect solution for me. I can use the standard @Rnd where appropriate, and I can use my custom @cuRnd just before sending a value to a money element. I'm happy with that.  Smiley
  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
Carl Underwood
Senior Member
Members
*****
Offline



Posts: 1351
Location: New Hampshire
Joined: Mar 11th, 2003
Re: Money Format
Reply #13 - Apr 2nd, 2005 at 12:53am
Print Post Print Post  
I have updated the code I posted earlier, it now handles negative numbers properly.

Here it is:

Code
Select All
//########## Begin Custom Rounding Function ##########
Function @cuRnd(Value as double, Places as int)

var Neg as int	//Used to handle Negatives properly

if Value < 0
	Neg = -1
else
	Neg = 1

Value = @Abs(Value)

if @Instr(Value, ".") > 0	//Protects whole numbers when rounding to zero places
	{
	if @Mid(Value, @Instr(Value, ".") + Places + 1, 1) >= 5
		Value = Value + (1 / @Exp(10, Places))
	Value = @Del(Value, @Instr(Value, ".") + Places + 1, 10)
	}

Value = Value * Neg

Return value

End Function
//########## End Custom Rounding Function ##########
 



EDIT: The code was modified again to protect whole numbers when rounding to zero places. Also, the @Exp() function was added to allow proper rounding to places other than hundredths.


@cuRnd(V, P)
Parameters: V as Double, P as Integer
Returns: Double

Rounds off the value of V to P decimal places. Unlike the regular @Rnd function, the value of P must be a positive number, meaning that it is only designed to round to whole numbers or to tenths, hundredths, thounsandths, etc. - not to the nearest tens, hundreds, etc.
« Last Edit: Apr 2nd, 2005 at 4:14am by Carl Underwood »  


Carl Underwood
CDU Computer Consulting LLC
Epsom, New Hampshire
Back to top
IP Logged
 
Hammer
YaBB Administrator
Lanticans
*****
Offline


Fire bad. Tree pretty.

Posts: 3436
Location: Ohio
Joined: Nov 22nd, 2002
Re: Money Format
Reply #14 - Apr 2nd, 2005 at 6:21pm
Print Post Print Post  
Good job, Carl.  Smiley

That's one of the nice things about SBasic. While we (as product developers) have to play by rules that meet generalized requirements, the tools provided by SBasic allow you develop solutions for yourself that work for your specific requirements. Thanks for sharing this with others who may want the same behavior.

You might consider posting this to the Programming  Examples board and/or submitting it to Inside Sesame as a Tip.

Also, may I suggest redoing it slightly as something like shown below.  It's untested as I am not at a computer with Sesame, so you probably want to check it out yourself. The changes are:
1. The return type of the Function is declared, so it does not accidentally get forced to an Integer.
2. A separate variable is used to return, rather than taking over an argument. The results of returning a passed in argument can be unpredicatable.

Code
Select All
//########## Begin Custom Rounding Function ##########
Function @cuRnd(Value as double, Places as int) as Double

var Neg as int //Used to handle Negatives properly
var vRet as Double

if Value < 0
 Neg = -1
else
 Neg = 1

vRet = @Abs(Value)

if @Instr(vRet, ".") > 0 //Protects whole numbers when rounding to zero places
 {
 if @Mid(vRet, @Instr(vRet, ".") + Places + 1, 1) >= 5
  vRet = vRet + (1 / @Exp(10, Places))
 vRet = @Del(vRet, @Instr(vRet, ".") + Places + 1, 10)
 }

vRet = vRet * Neg

Return vRet

End Function
//########## End Custom Rounding Function ##########  



BTW, this code repeatedly treats a number as a String without explicilty converting it first, which means that SBasic is converting it back and forth several times as you go, so you may want to keep an eye on this for anomalies caused by the repeated type conversions.

Just my $0.019999 cents.  Wink
  

- Hammer
The plural of anecdote is not data.
Back to top
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send Topic Send Topic Print Print