在Java中使用模式##### 0.00的DecimalFormat奇怪行为

时间:2015-07-22 12:23:51

标签: java floating-point format decimalformat

我使用下面的代码捕捉来显示带有两个小数点的NumberFormat FORMAT = new DecimalFormat("#####0.00"); float myFloatValue =\\I am able to fetch this value dynamically String finalPrice = FORMAT.format(myFloatValue); // I am using this String (finalPrice) for export xml purpose. 价格值。

finalPrice

它似乎正常工作正常,但我注意到一些例子(如下所示)它没有正常工作并产生超过两个小数点的价格。我无法再次复制它,我只能在日志文件中看到它。

myFloatValue字符串的一些示例输出: 0.10999966 0.1800003 0.45999908

有人可以帮助我从这些输出中猜出<?php class Puzzle { var $pos; var $sequence; var $depth; function __construct($current_pos) {  $this->pos = $current_pos; $this->sequence = array(); $this->depth=1;  } function goalTest($goal) {      if ($this->pos === $goal) {        return True;         } else { return False;         }  } function possibleMoves() {      $Moves = array();      for ($i = 0; $i < 3; $i++) {    for ($j = 0; $j < 3; $j++) {    if ($this->pos[$i][$j] == 0) {   break 2;                 }   }      } $this->checkMove($i, $j, $i - 1, $j, $Moves);    $this->checkMove($i, $j, $i + 1, $j, $Moves);   $this->checkMove($i, $j, $i, $j - 1, $Moves); $this->checkMove($i, $j, $i, $j + 1, $Moves); return $Moves; } function moveBlank($srcRow, $srcCol, $destRow, $destCol) {    $newpos = $this->pos;     $tmp = $newpos[$destRow][$destCol]; $newpos[$destRow][$destCol] = $newpos[$srcRow][$srcCol];  $newpos[$srcRow][$srcCol] = $tmp; return $newpos;   } function InSequence($pos) {  for ($i = 0; $i < count($this->sequence); $i++) {  if ($this->sequence === $pos) {         return TRUE;            }         }         return FALSE; } function canMove($srcRow, $srcCol, $destRow, $destCol) {  if ($srcRow < 0 or $srcCol < 0 or $destRow < 0 or $destCol < 0) {   return FALSE;         }  if ($srcRow > 2 or $srcCol > 2 or $destRow > 2 or $destCol > 2) {  return FALSE;         }  return TRUE;     } function checkMove($srcRow, $srcCol, $destRow, $destCol, & $Moves) {       if ($this->canMove($srcRow, $srcCol, $destRow, $destCol)) {  $newpos = $this->moveBlank($srcRow, $srcCol, $destRow, $destCol);       if (!$this->InSequence($newpos)) {        $newMove = new Puzzle($newpos);       $newMove->sequence = array_merge($this->sequence); $newMove->sequence[] = $newpos;            $Moves[] = $newMove;            } }    } function printSequence() { for ($i = 0; $i < count($this−>sequence); $i++) { print ("Step $i −−−−−−−<br> "); $this−>printPos($this−>sequence[$i]); print("<br>"); } } function printPos($pos) { for ($i = 0; $i < 3; $i++) { for ($j = 0; $j < 3; $j++) { print(" " . $pos[$i][$j] . " "); } print("<br>"); } } } $start_time = microtime(); $initial_pos = array( array(2, 8, 3), array(1, 6, 4), array(7, 0, 5) ); $goal_pos = array( array(1, 2, 3), array(8, 0, 4), array(7, 6, 5) ); $initial_state = new Puzzle($initial_pos); $initial_state−>sequence[] = $initial_pos; $nodeQue = new SplQueue(); $nodeQue−>enqueue($initial_state); $nodeQue−>rewind(); $i = 1; while ($nodeQue−>valid()) { $i++; if ($i % 10000 == 0) { print("$i steps have been finished<br>"); print("Unopened Nodes left in the Que = " . $nodeQue−>count() . "<br>"); $end_time = microtime(); $exec_time = $end_time − $start_time; print ("Time executed to $i steps is $end_time <br>"); } $current_state = new Puzzle(); $current_state = $nodeQue−>dequeue(); if ($current_state−>goalTest($goal_pos) == TRUE) { print("Solution found in $i steps<br>"); print("Unopened Nodes left in the Que=" . $nodeQue−>count() . "<br>"); $current_state−>printSequence(); break; } $moves = $current_state−>possibleMoves(); foreach ($moves as $move) { $nodeQue−>enqueue($move); } $nodeQue−>rewind(); } print ("<br>Maximum Memory used " . memory_get_peak_usage()); print ("<br>Current Memory used" . memory_get_usage()); $end_time = microtime(); $time_exec = $end_time − $start_time; print("<br>Execution time used =" . $time_exec); ?> 的原始值吗?这样它将帮助我复制场景并修复它。

1 个答案:

答案 0 :(得分:2)

偶发事件让我想知道DECIMAL_FORMAT是否同时在多个线程中使用。这是禁忌。然而人们会期待 错误的值。

也许为了良好的顺序也指定一个固定的Locale(小数点与逗号,千位分隔符)。

最后float甚至double不适用于财务软件:这些数字是近似值。

BigDecimal price = new BigDecimal("9.99");
price = price.multiply(BigDecimal.TWO); // 19.98 exact

BigDecimal是用于编写计算的PITA,但保持其精确度。