2009-08-29 19 views
15

私は、ファイルから動的に変化する入力読み取り値を持っています。数字はIntまたはDoubleのいずれかです。 Doubleの番号の後にScalaが.0を印刷するのはなぜですか? Scalaがそれを読み取るのと同じ方法で印刷する方法はありますか?Scalaでの数値書式設定は?

例:私が手入力の一部がDouble sがあるので、私はIntを使用することはできません

var x:Double = 1 
println (x)    // This prints '1.0', I want it to print '1' 
x = 1.0     // This prints '1.0', which is good 

StringまたはAnyValを使用することはできません。数学演算を実行するためです。フォーマット文字列の説明については

printf("The value is %.0f", x) 

、Java SEの6 APIのドキュメントからthis pageを参照してください。

は、

答えて

7

使用printf、ありがとうございました。

でもScalaのJavaライブラリを使うこともできますので、Javaから数値をフォーマットする他の方法もScalaから使用できます。私はあなたがScalaは異なり、xとyを印刷したい質問を理解している場合

val df = new java.text.DecimalFormat("#####") 
println(df.format(x)) 
+0

あなたのためのおかげで を返信しかし、問題は数が不明であることで、どちらかそれは「1」または「1.0」です。 '1'なら '1'を、 '1.0'なら '1.0'を出力したい。しかし、Doubleであるため、Scalaは常に '1.0'として出力します。 –

+3

これを望むなら、文字列として格納する必要があります。 'double'はあなたが' 1'または '1.0'でそれを割り当てたかどうか覚えていません。 – cdmckay

+2

鼓道、数字は本質的に数字ではありません。値1を持つ数値と値1.0を持つ数値の間には違いはありません。 – Jesper

9
var x:Double = 1 
var y:Double = 1.0 

print(x) // => 1.0 
print(y) // => 1.0 

:あなたは使用例クラスjava.text.DecimalFormat用できますか?問題は、xとyが両方ともDouble型の変数であり、同じように見えるということです。

明示的にヴァルスの種類を定義していますか?

var x = 1 
var y= 1.0 

print(x) // => 1 
print(y) // => 1.0 
+0

彼は "ファイルから入力読み取り値を動的に変更する"と述べました。彼は数値を持っていますし、数値は整数でもなくてもかまいません(しかし、常にDoubleとして保存されます)。 – akauppi

1

明示的な型定義ではなく型推論を使用します。

scala> val xi = 1 
xi: Int = 1 

scala> val xd = 1.0 
xd: Double = 1.0 

scala> println(xi) 
1 

scala> println(xd) 
1.0 
+0

申し訳ありません、これは重複した回答です。 – Synesso

29
scala> "%1.0f" format 1.0 
res3: String = 1 

あなたの入力がIntDoubleのいずれかである場合、あなたはこのようにそれを行うことができます。

def fmt(v: Any): String = v match { 
    case d : Double => "%1.0f" format d 
    case i : Int => i.toString 
    case _ => throw new IllegalArgumentException 
} 

使用法:それ以外の場合は

scala> fmt(1.0) 
res6: String = 1 

scala> fmt(1) 
res7: String = 1 

scala> fmt(1.0f) 
java.lang.IllegalArgumentException 
     at .fmt(<console>:7) 
     at .<init>(<console>:6) 
     at .<clinit>(<console>) 
     at RequestResult$.<init>(<console>:4) 
     at RequestResult$.<clinit>(<console>) 
     at RequestResult$result(<console>) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.Dele... 

、あなたはBigDecimalsを使用する場合があります。彼らは遅いですが、彼らは、スケールが付属していないので、「1」、「1.0」と「1.00」全て異なっている:

scala> var x = BigDecimal("1.0") 
x: BigDecimal = 1.0 

scala> x = 1 
x: BigDecimal = 1 

scala> x = 1.0 
x: BigDecimal = 1.0 

scala> x = 1.000 
x: BigDecimal = 1.0 

scala> x = "1.000" 
x: BigDecimal = 1.000 
+0

それはひどいです。すべてのタイプの安全を窓から投げただけです。最も簡単な方法は次のとおりです。 n.toInt.toString – juancn

+4

@juancnどのようにしてウィンドウからタイプセーフを捨てましたか?ちなみに、 "var n = 1.0; n.toInt.toString'"は、必要に応じて '1.0'ではなく、' 1'を生成します。 –

+2

事実、 'fmt'では、実際には真ではない「Any」を受け入れると言っています。文字列を渡すとIllegalArgumentExceptionがスローされるからです。あなたは次のようなことができます: 'def fmt [T <%math.ScalaNumericConversions](n:T)= if(n.toInt == n)n.toInt.toString else n.toString'これは安全です。 型システムが合理的な制約のセットを表すことができない場合(たとえば、スカラーでは、長整数型を型として指定することができない場合など)、不正な引数例外がスローされます。 – juancn

4

浮動小数点の末尾に「_.0」の使用数字は規約です。数値が浮動小数点であり、整数ではないことを知るための単なる方法です。

本当にの場合は、「読み取るのと同じ方法で印刷する」必要がある場合は、コードが構造化されているかどうか再考する必要があります。それだけで書式設定の問題だ場合、最も簡単な方法は、印刷する前に、整数に値を変換することです:

def fmt[T <% math.ScalaNumericConversions](n : T) = 
        if(n.toInt == n) n.toInt.toString else n.toString 

val a : Double = 1.0 
val b : Double = 1.5 
val c : Int = 1 

println(fmt(a)) 
println(fmt(b)) 
println(fmt(c)) 

val x = 1.0 
println(x.toInt) 

一部は整数であり、一部ではない場合は、もう少しコードが必要上記のコードは、印刷する必要があり:

1 
1.5 
1 

fmtメソッドのシグネチャのいずれかScalaNumericConversionsのサブタイプであるまたは1つに変換することができる任意のタイプを受け入れ

暗黙的な変換によって( toIntメソッドを使用できます)。 Scalaの2.10以降で

2

あなたはthe f interpolatorを使用することができます。

scala> val x: Double = 1 
x: Double = 1.0 

scala> println(f"$x%.0f") 
1 

scala> val i = 1 
i: Int = 1 

scala> println(f"$i%.0f") 
1 
関連する問題