2011-12-20 7 views
24

は、これを入力してください。タイプ、INT、など

scala> 86400000 * 150 
res0: Int = 75098112 


scala> val i : Long = 86400000 * 150 
i: Long = 75098112 


val i = 86400000 * 150.asInstanceOf[Long] 
i: Long = 12960000000 

val i = 86400000 * 150L 
i: Long = 12960000000 

世界でここで何が起こっているの?私はスカイダイビングをしていて、これは私が今までに見た中で最も危険なことだと言わざるを得ない。このためのコンパイラチェックはありませんか?明らかに、もし私が違う変数に150を代入していたら?

* EDIT *

これは私が心配していた実際のコードでした。

val oneDay = 86400000 
val days150 = oneDay * 150 

days150 = 75098112 

これは、私自身以外のScalaのフォルトまたはフォールトフォルトではありませんでした。ちょうど私が心配した。

+13

この質問に投票しないでください。これは正当な質問であり、整数のオーバーフローは非常に危険であり、実際のプログラムで実際の問題を引き起こします。 Scalaだけではなく、多くの言語で共通するという事実は、価値のある投票にはならないということです。 –

+1

本当に大きな番号が必要な場合は、常に[BigInteger](http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigInteger.html)があります。少し不器用ですが、うまくいきます。 –

+1

投票に参加しました。これは質問よりも暴言です。さまざまな例は、質問者が何が起こっているかを正確に知っていることを示しています。 –

答えて

15

これについては、Scala固有のことはありません。これは、操作(この場合は乗算)が実行されるタイプとは無関係な割り当てのターゲットタイプの問題です。例えば

は、C#で:C#コンパイラは、操作がオーバーフローすることを実現するのに十分なスマートですので

using System; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     int a = unchecked(86400000 * 150); 
     long b = unchecked(86400000 * 150); 
     long c = 86400000 * (long) 150; 
     long d = 86400000 * 150L; 
     Console.WriteLine(a); // 75098112 
     Console.WriteLine(b); // 75098112 
     Console.WriteLine(c); // 12960000000 
     Console.WriteLine(d); // 12960000000 
    } 
} 

ここunchecked部分があるが、両方のオペランドが定数であるという理由だけで。いずれかのオペランドが変数であった場合、uncheckedなしで正常だったでしょう。 Javaで同様に

public class Program 
{ 
    public static void main(String[] args) 
    { 
     int a = 86400000 * 150; 
     long b = 86400000 * 150; 
     long c = 86400000 * (long) 150; 
     long d = 86400000 * 150L; 
     System.out.println(a); // 75098112 
     System.out.println(b); // 75098112 
     System.out.println(c); // 12960000000 
     System.out.println(d); // 12960000000 
    } 
} 
+0

ありがとうございます。私は何らかの理由でJavaでこの問題に気付かなかっただけです。 –

+3

Blame C. ScalaとC#はJavaから固定サイズの整数ルールをコピーし、Javaは基本的にC++のルールをコピーしてCからクローンを作成しました。 –

+4

これはFORTRANからASMを取得しました。悲しい。私たちは、父が生まれたときに存在しなかった職業に属しています。私たちは、古代文章を掘り下げているタルムード学者のような学者です。 – Malvolio

0

それが起こって暗黙のキャストがない明らかです。 86400000 * 150はと表示されています。私はjvmを想像しています。それは、差異を生じさせない任意の変数タイプuに割り当てられます。だから正しいことは、数字または変数の少なくとも1つが長い型としてキャストされることを確認することです。86400000 * 150.toLong jvmは、より大きな型にデフォルト設定されているようです。

Btw、私はスカラの終わりのオーバーフローチェックがパフォーマンスを損なうと信じています。したがって、自動型変換の省略はリスクをもたらしますが、より良いパフォーマンスを可能にします。注意する必要があります...あなたがc/C++のバックアップから来たのであれば、それは第二の性質でなければなりません。

関連する問題