日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java long 溢出_关于溢出:Java乘法运算行为

發(fā)布時間:2024/9/15 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java long 溢出_关于溢出:Java乘法运算行为 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我編寫了一種方法,可以將給定的數(shù)字從幾天轉(zhuǎn)換為毫秒:

private long expireTimeInMilliseconds;

...

public void setExpireTimeInDays(int expireTimeInDays)

{

expireTimeInMilliseconds = expireTimeInDays * 24 * 60 * 60 * 1000;

}

我很難找出我做錯了什么。 現(xiàn)在我的問題是:

那個錯誤是如此明顯嗎?

更正的方法:

private long expireTimeInMilliseconds;

...

public void setExpireTimeInDays(int expireTimeInDays)

{

expireTimeInMilliseconds = ((long) expireTimeInDays) * 24 * 60 * 60 * 1000;

}

如果在計算之前不將整數(shù)轉(zhuǎn)換為很長的時間,則會得到完全錯誤的結(jié)果。

您也可以在常量后面加上L。

人們?yōu)槭裁匆P(guān)閉它? 似乎是一個可以幫助他人的正當(dāng)問題。 如果確切重復(fù),請這樣說。

您還可以聲明常量:long 24L * 60L ...

有趣的話題,但我認(rèn)為這里的實際問題需要更改。"錯誤是否明顯"很容易受到影響。 諸如"為什么即使我的變量為long類型,Java為何也不能將其轉(zhuǎn)換為long?" 似乎是這里實際討論的內(nèi)容。

@Outlaw你是對的:" Java為什么不將其轉(zhuǎn)換為long"在這里比較合適。

明顯嗎?我想這取決于您使用Java已有多長時間,以及必須處理多少次毫秒。當(dāng)然,最多可以保留24天左右...

我認(rèn)為最大的提示應(yīng)該是System.currentTimeMillis()返回long。這很好地表明了毫秒數(shù)可能會變大。您要設(shè)置的變量的類型也應(yīng)該是一個很好的提示。

當(dāng)然,您還必須了解,如果使用int進(jìn)行算術(shù)運算,結(jié)果將是int,并在溢出時進(jìn)行環(huán)繞。是否足夠明顯尚有爭議,但這將是毫無意義的討論。在C#中,如果您打開了溢出檢查功能,您會很快發(fā)現(xiàn)該錯誤-但是沒有那么多開發(fā)人員這樣做(實際上,我可能不會這樣做)。

我期待一個很長的時間,我曾經(jīng)使用過System.currentTimeMillis()。因為那不是一個新代碼,所以我記不起編寫它時的想法(可能是我期望編譯器提供一些魔術(shù))...

...我認(rèn)為,就像您所說的那樣,我最大的錯誤是使用int進(jìn)行算術(shù)運算,而沒有注意int溢出。我忘記了基本概念(實際上我沒有為Java學(xué)習(xí),但我已經(jīng)為C / C ++學(xué)習(xí))

是的,如果您之前已經(jīng)做過,那就很明顯了。每當(dāng)您看到一串?dāng)?shù)字相乘時,都應(yīng)該自動開始考慮整數(shù)溢出錯誤。在這種情況下,如果expireTimeInDays大于24,則設(shè)置為溢出。從技術(shù)上講,您應(yīng)該在處理整數(shù)時隨時考慮溢出錯誤,但是像這樣將它們相乘應(yīng)該是一個很大的危險信號。

您可能想知道Joshua Bloch和Neal Gafter撰寫的" Java Puzzlers"中對此進(jìn)行了介紹。

(來源:javapuzzlers.com) sub>

您將在本書中發(fā)現(xiàn)許多其他的Java陷阱,陷阱和極端案例。

我同意發(fā)表評論的繁星點點。在數(shù)字后面加上L。

您的操作數(shù)變量和文字?jǐn)?shù)字的類型為int。 int數(shù)據(jù)類型的最大值為2 ^ 31 -1。因此,使用如此大的數(shù)字,int的數(shù)據(jù)類型會溢出,從而導(dǎo)致看似錯誤的答案。

在您的第一個示例中,僅將int賦值給在計算后出現(xiàn)的變量上很長的賦值。計算結(jié)果為整數(shù)。

第二個示例將第一個操作數(shù)強(qiáng)制轉(zhuǎn)換為long,導(dǎo)致將計算提升為long。在這種情況下,由于提升,計算的結(jié)果很長。 long數(shù)據(jù)類型足以進(jìn)行計算。

看起來Java具有與C相同的int溢出行為。我想我期望編譯器為我將其轉(zhuǎn)換(int到long)。它的代碼看起來很簡單(就是這樣)...我只需要更加注意。

不,這不是顯而易見的。

但是請相信我,經(jīng)過幾年的實踐并修復(fù)了此類錯誤之后,您對整數(shù)溢出變得非常明智,甚至在做正確的事情時都沒有考慮它。

這件事發(fā)生在每個人身上。絕對沒有不良實踐,無知之類的跡象。

有趣的是,我已經(jīng)編碼了20多年,這是我第一次犯該特定錯誤。當(dāng)我是C / C ++開發(fā)人員時,我曾經(jīng)注意代碼中的每個小細(xì)節(jié)。我認(rèn)為現(xiàn)在我希望編譯器為我做一些"魔術(shù)" ...

有一些靜態(tài)分析工具(findbug)可以找到這些類型的錯誤。

在計算機(jī)上進(jìn)行數(shù)字?jǐn)?shù)學(xué)可能很困難。操作順序問題可能會以您意想不到的方式影響精度和準(zhǔn)確性。日期數(shù)學(xué)也可能非常棘手。通常,使用Date / Calendar例程比嘗試自己做數(shù)學(xué)要好,但是這些例程并不是Java類庫中設(shè)計最好的例程。

如果在代碼上使用FindBugs,它將檢測到此確切問題。" ICAST:整數(shù)乘法的結(jié)果強(qiáng)制轉(zhuǎn)換為long。" FindBugs的示例正是您在做什么;計算天數(shù)(以毫秒為單位)。

第一次遇到這個問題對我來說并不明顯。

另一種寫方法是

public void setExpireTimeInDays(int expireTimeInDays)

{

expireTimeInMilliseconds = (long) expireTimeInDays * 24 * 60 * 60 * 1000;

}

要么

public void setExpireTimeInDays(int expireTimeInDays)

{

expireTimeInMilliseconds = expireTimeInDays * 24L * 60 * 60 * 1000;

}

這樣比較好,我寧愿避免不必要的轉(zhuǎn)換。謝謝

只是為了增加其他答案,我發(fā)現(xiàn)在過去定義常量(public static final long)如MILLISECS_DAY或MILLISECS_HOUR很有幫助。

更具可讀性和實用性。

我并不是想證明我的錯誤,但是如果Java編譯器足夠聰明,可以在計算之前很長一段時間將int提升到很長時間(一旦將計算分配給long類型的變量),那將是很好的選擇

順便說一下,我曾經(jīng)使用過C / C ++,如果它是C程序,我也會遇到同樣的問題,但是幾年前,我對這種操作更加謹(jǐn)慎。

下次我會更加關(guān)注(或切換到python)...:D

總結(jié)

以上是生活随笔為你收集整理的java long 溢出_关于溢出:Java乘法运算行为的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。