3

Why does NumberFormat(".##").format(17.46) leads to a string of 17.46 and not .46?

How can I achieve the latter, i.e. remove all digits in front of the decimal sign?

Heikkisorsa
  • 740
  • 9
  • 31
  • Have you tried changing the property ```maximumIntegerDigits``` of the NumberFormat class to zero before calling ```format```? Either way I agree with you that this is a counterintuitive result. – Naslausky Jul 30 '20 at 13:03
  • @Naslausky maximumIntegerDigits can not be set, although they are in the API Docs. Or at least I have not found a working example yet. – Heikkisorsa Jul 30 '20 at 13:18

3 Answers3

2

The NumberFormat only changes the way that a number is being displayed(basically, what formatting is). So you can't get the fractional part of the number(it doesn't work like pattern matching). Instead, you can use:

var num = 17.46;
var fraction = num.toString().split('.')[1];

Note: you can use '.' + num.toString().split('.')[1] to get the fraction part with the starting dot.

You can read more about the ICU Formatting that NumberFormat uses in this link.

Mobina
  • 6,369
  • 2
  • 25
  • 41
  • If it only changes the way the number is displayed I don't see a contradiction to my problem, since it is basically the same as saying: show me maxIntegeDigits=0 which is an actual parameter of the package. The result I am getting here is very misleading in my opinion. – Heikkisorsa Jul 30 '20 at 18:52
0

‘#’ in the NumberFormat class marks a single digit (omitted if the value is zero). So the number of hashtags after the decimal point denotes how many decimal places you want. For example:

double number = 12.1234;
NumberFormat(".#").format(number);     //prints 12.1
NumberFormat(".##").format(number);    //prints 12.12
NumberFormat(".###").format(number);   //prints 12.123
NumberFormat(".####").format(number);  //prints 12.1234

You could use substring and indexOf to remove everything before the decimal point, like so:

String str = "12.36";
String newStr = str.substring(str.indexOf('.') + 1);
//If you want to include the decimal point, remove the + 1.
HBS
  • 580
  • 3
  • 6
  • How does this answer the question `"Why does NumberFormat(".##").format(17.46) leads to a string of 17.46 and not .46?"` ? If you even use 0 instead of #, it still doesn't work. – Mobina Jul 30 '20 at 13:17
  • @HBS Your fix works, however it does not explain the behavior of the NumberFormat method. – Heikkisorsa Jul 30 '20 at 13:26
  • @Heikkisorsa Added some examples. Hopefully, it makes sense now. – HBS Jul 30 '20 at 21:32
  • @HBS Thanks for the example. However, the behavior is still counterintuitive in my opinion and the API Docs are not correct regarding what properties one can set for the formatting. – Heikkisorsa Jul 31 '20 at 06:17
0

Just as an alternative to the other answer, you can try to remove the integer part before converting to String, and not after:

String formatFraction (num a){
  num b = a.floor();
  num c = a-b;
  return NumberFormat(".##").format(c);
}

This way you can guarantee it will work despite of locale.

Naslausky
  • 3,443
  • 1
  • 14
  • 24
  • 1
    Be aware that the above code might not do what's expected for negative numbers. If you want to extract `-0.46` from `-17.46`, use `a.toInt()` instead of `a.floor()` so that you round toward zero instead of toward negative infinity. – jamesdlin Jul 30 '20 at 18:34
  • Also this solution might have problem with precision in rare cases – Heikkisorsa Jul 30 '20 at 18:41