質問
2桁の7桁の数値(ソースとターゲットのレコード数)を取得して、ターゲット数の欠落レコードの割合を計算しようとしています。
たとえば、私のレコード数は、ソースで4084094、ターゲットで4081313になります。また、次の式を使用してパーセンテージを計算しています:((1-(target / source))* 100)
私の例では、約.0681%の値を取得する必要があります
私はJavaとJSPが初めてで、パーセンテージを正しく表示することができません。値は0に切り捨てられるだけです。
BigDecimalも試しましたが、役に立ちませんでした。
次の簡単なコードでも1-1の値が表示されるため、明らかに重大な問題が発生しています。
<%
BigDecimal percentMiss;
long tmp = 600/500;
percentMiss = BigDecimal.valueOf(tmp);
%>
<%=percentMiss.toString()%>-<%=tmp%>
解決
問題は次の行にあります
long tmp = 600/500;
浮動小数点数をlongに格納することはできません。代わりに、次のコードの使用を検討する必要があります。
double tmp = (double)600 / (double)500;
次にtmpを表示します。この値は0から1の間の値になります(計算を500/600に変更する必要があるため、1.2の場合)
他のヒント
問題は明らかに、2つの長い数字を分割していることです。
DecimalFormat を使用することをお勧めしますa>番号を表示します。 JSTLを使用している場合は、タグのフォーマット:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatNumber value="${value}" minFractionDigits="2" maxFractionDigits="2"/>
あなたの問題は、600と500が整数値であり、それらの間の除算が整数の結果を持ち、それを長整数に割り当てることです。この後、結果の小数部分はなくなり(2回)、元に戻すことはできません。
小数の結果を得るには、除算の入力値の少なくとも1つが非整数である必要があります。これを実現するには、それらを double
または float
にキャストするか、リテラルを次のように明示的にdoubleまたはfloatにします。
500.0 // implicitly double
500f // float literal
500d // double literal
ただし、double / float divisonの結果を印刷すると、結果に含まれてはならない場合でも、必要以上に小数点以下の桁数が多くなることがあります(たとえば、 1/10
は 0.100000001490116119384765625
)、これらの数値が2進小数として格納される方法 >。
これらの不要な数字は java.lang.DecimalFormat
を使用して削除できますが、 BigDecimal
は小数を内部的に使用するため、実際には丸めモードを正確に制御しながら、結果を修正します。もちろん、これには、「ブードゥー成分」としてではなく、計算自体に BigDecimal
を使用する必要があります。既に壊れている結果を修正します。
new BigDecimal(600).divide(new BigDecimal(500))
BigDecimalのAPIドキュメントを読む
で詳細をご覧ください。