You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by "Daniel Dekany (JIRA)" <ji...@apache.org> on 2018/08/08 15:33:00 UTC

[jira] [Commented] (FREEMARKER-102) ${float?string('0.##;; roundingMode=halfUp')}

    [ https://issues.apache.org/jira/browse/FREEMARKER-102?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16573378#comment-16573378 ] 

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: https://issues.apache.org/jira/browse/FREEMARKER-102
>             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
(v7.6.3#76005)