freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Daniel Dekany (JIRA)" <>
Subject [jira] [Commented] (FREEMARKER-102) ${float?string('0.##;; roundingMode=halfUp')}
Date Wed, 08 Aug 2018 15:33:00 GMT


Daniel Dekany commented on FREEMARKER-102:

Surely it's anti-intuitive if you look at the Java source code, but 172.52 is in fact the
right answer, as 172.525f is 172.524993896484375. That's why people almost never use floating
point for non-integer numbers, except for physics, graphic and such. Use {{BigDecimal}} otherwise.
Floating point is tricky and imprecise.

Regarding the {{BigDecimal}} trick you have applied, it's actually an artifacts of doing
two roundings. The basic string conversion of Java cheats and tries to restore how the literal
has looked in the source code be rendering it as 172.525, then since {{BigDecimal}} has
no problem storing that number precisely, the number that was originally 172.524993896484375
has been rounded to 172.525. Then the {{DecimalFormat}} rounds it yet again, upwards.

As of the {{double}} conversion issue, it doesn't cause further loss. Like if you put {{double}}-s
into the data-model, you will still experience that some(!) numbers are unexpectedly rounded
down. (Though your example numerical literal without the {{f}} happens to be greater than
172.525, so you won't see the phenomenon there, but you will with 162.535 for example.)

So I would close this as not a bug.

> ${float?string('0.##;; roundingMode=halfUp')}
> ---------------------------------------------
>                 Key: FREEMARKER-102
>                 URL:
>             Project: Apache Freemarker
>          Issue Type: Bug
>    Affects Versions: 2.3.28
>            Reporter: minglaing ma
>            Priority: Major
>   Original Estimate: 12h
>  Remaining Estimate: 12h
> java
> Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
>  configuration.setClassForTemplateLoading(new Main().getClass(), "/jigndu");
>  Template template = configuration.getTemplate("index.ftl");
> Map<Object,Object> root =new HashMap<Object, Object>();
>  root.put("float", 172.525f);
>  Writer out =new OutputStreamWriter(System.out);
>  template.process(root, out);
> ftl
> ${float?string('0.##;; roundingMode=halfUp')}
> output
> 172.52
> I think 172.53 is right
> the reason is 
> java.text.NumberFormat  format method   param is a double,now i use a float。
>  when float to double wrong,i  think
>  freemarker.core.JavaTemplateNumberFormat.format  method should
>  if (number instanceof Float)
> { return javaNumberFormat.format(new BigDecimal(String.valueOf(number))); }
> return javaNumberFormat.format(number);

This message was sent by Atlassian JIRA

View raw message