decimal_format.ash

Catch-22

Active member
Perhaps we need an ASH "format" function that interfaces the Java's DecimalFormat.

Of course Veracity was referring to a native ASH function, but where's the fun in that? :)

I've implemented a simple decimal_format function using existing ASH functions.

string decimal_format( float, [int], [boolean] )
Returns a string formatted to the specified precision (defaults to 7) and rounding (defaults to true).

It's not going to be perfect due to the way some floats work, but it's something.

Code:
> call decimal_format.ash 0.1

0.1

> call decimal_format.ash 1.1

1.1

> call decimal_format.ash 1.123

1.123

> call decimal_format.ash 123.456

123.4560012

> call decimal_format.ash 123456789.123456789

123456792.0
 

Attachments

  • decimal_format.ash
    1.3 KB · Views: 52
Last edited:

Bale

Minion
LoL! You reverse the digits to keep 00010 from being turned into 10! You even get rid of trailing zeroes that way instead of dividing by 10**p!

That's awesomely funny the way it's so counter-intuitive and effective. I love it!

I'd just do one little thing to make it simpler to read. You use whole.index_of(".")+1 in 4 different places. Assign that value to an integer:

PHP:
string decimal_format(float myFloat, int precision) {
  precision = min(9, precision);
  string whole = myFloat.to_string();
  int dec = whole.index_of(".")+1;
  string partA = whole.substring(0, dec);
  precision = min(precision, length(whole.substring(dec)));
  string partB = whole.substring(dec, dec+precision);
  
  partB = partB.reverse().to_int().to_string().reverse();
  
  return partA+partB;
}

Its only flaw is that using 2 digits of precision, it won't round 1.225 to 1.23
 
Last edited:

Catch-22

Active member
LoL! You reverse the digits to keep 00010 from being turned into 10! You even get rid of trailing zeroes that way instead of dividing by 10**p!

That's awesomely funny the way it's so counter-intuitive and effective. I love it!

Haha, thanks, I liked it too. I took it out in the new version though, even though it was funny. The new version is more robust and not limited to a maximum of 9 decimal places, it also implements your change.

If anyone wants a string reversal function for some reason, here's the function I wrote.

PHP:
string reverse(string myString) {
  buffer reverse;
  for i from myString.length()-1 downto 0 {
    reverse.append(myString.char_at(i));
  }
  return reverse.to_string();
}

Its only flaw is that using 2 digits of precision, it won't round 1.225 to 1.23

Yeah, I noticed that too. It's really only a small function designed to prevent you from having huge numbers output to your users when you wanted to just say 1.1, but if you're actually interested in a function that does this I'd be happy to help. It's definitely possible using current ASH functions, but if Veracity's comments become a reality it might not be worth the extra effort :)
 
Last edited by a moderator:

Bale

Minion
I've shortened it a little bit and am now using the following for Chit.

PHP:
string decimal_format(float myFloat, int precision) {
  string whole = myFloat.to_string();
  int dec = whole.index_of(".")+1; //Good idea, Bale :)
  precision = min(precision, length(whole.substring(dec)));
  string partB = whole.substring(dec, dec+precision);
  while ( partB.char_at(partB.length()-1) == "0" && (partB.length() > 1) )
    partB = partB.substring(0, partB.length()-2);
  
  return whole.substring(0, dec)+partB;
}

Thank you!
 

Catch-22

Active member
I've shortened it a little bit and am now using the following for Chit.

Thank you!

You're welcome. As you're actually using this instead of just admiring it, I went ahead and implemented rounding (can be disabled, but defaults to being on).

This is probably the last update I will make to the function unless there's some glaring bug that breaks it.
 

Bale

Minion
I guess that works, but it is so ugly. I'll think about rounding. It's not really essential for my purpose.
 

Ethelred

Member
...

Its only flaw is that using 2 digits of precision, it won't round 1.225 to 1.23

Actually, the last time I took a course that dealt with such things, there was a faction that felt 1.225 should be rounded to 1.22. The rationale was that a number ending with 5 followed by infinite 0's, should be rounded down half the time and up half the time. To decide which way to round in a particular case, look at the preceeding digit. If even, round down; if odd, round up. But that was a long time ago and I have no idea what the is currently taught in numerical methods classes.
 

Winterbay

Active member
That way of thinking was phased out of Swedish schools some 20 years ago or so I think, nowadays it's said that 1-4 round down and 5-9 rounds up which gives a certain rounding bias I guess.
 
I believe which method you are taught depends on your teacher. When dealing with sigfigs I always round down for [even]5 and up for [odd]5. I suppose if significant figures aren't a matter of importance Veracity's method is rather brilliant.
 
Last edited:

Catch-22

Active member
You are actually quite right, there is a bias, and Java actually has a rounding type (ROUND_HALF_EVEN) to mitigate this bias using the very same method that Ethelred mentions.

I think it really depends on the application. I believe most calculations in KoL end up being rounded down (floored), for example if you had 2.8 meat, you'd actually only have 2 whole meat. I think 15% additional moxie on a character with 51 moxie will result in 58 moxie, not 59, but I could be wrong.

ROUND_HALF_EVEN could be implemented in the function using existing ASH functions, but I don't really want to do it. As I said, I won't be updating it any further unless someone finds a bug in the current behaviour. ROUND_HALF_EVEN could maybe be a possibility should this functionality ever become native to ASH, or if someone else feels like adding it in. If you don't have a need for rounding your numbers, I suggest you turn off rounding so that you can save a few instructions.
 

Veracity

Developer
Staff member
There is only a rounding bias if you are looking exclusively at positive (or negative) numbers.
 

Catch-22

Active member
As opposed to imaginary ones? Haha.

For the record, I don't think ROUND_HALF_EVEN is worthwhile because if you're doing something like:

Code:
a = 1.5
b = 2.5
c = Round(a)+Round(b)

and wondering why c doesn't equal 4, then there's something wrong with your code, not the rounding function.
 

Winterbay

Active member
There is only a rounding bias if you are looking exclusively at positive (or negative) numbers.

Indeed, which is quite often the case in most biological systems as well as many engineering cases (which are the two types I'm mostly in contact with).
 
Top