『壹』 java double 精度問題
這種計算肯定會丟失精度的。如果不想丟失精度,可以用BigDecimal來表示
『貳』 java double最大精度
System.out.println(Double.MIN_VALUE);
System.out.println(Double.MAX_VALUE);
這兩個是double的最小值和最大值~
『叄』 java裡面有沒有long double類型或者比double更精度的
Java中的原子操作包括:
1)除long和double之外的基本類型的賦值操作
2)所有引用reference的賦值操作
3)java.concurrent.Atomic.* 包中所有類的一切操作。
但是java對long和double的賦值操作是非原子操作!!long和double佔用的位元組數都是8,也就是64bits。在32位操作系統上對64位的數據的讀寫要分兩步完成,每一步取32位數據。這樣對double和long的賦值操作就會有問題:如果有兩個線程同時寫一個變數內存,一個進程寫低32位,而另一個寫高32位,這樣將導致獲取的64位數據是失效的數據。因此需要使用volatile關鍵字來防止此類現象。volatile本身不保證獲取和設置操作的原子性,僅僅保持修改的可見性。但是java的內存模型保證聲明為volatile的long和double變數的get和set操作是原子的。(from
http://www.iteye.com/topic/213794)
舉個例子來說:(example is from
http://stackoverflow.com/questions/17481153/long-and-double-assignments-are-not-atomic-how-does-it-matter)
public class UnatomicLong implements Runnable {
private static long test = 0;
private final long val;
public UnatomicLong(long val) {
this.val = val;
}
@Override
public void run() {
while (!Thread.interrupted()) {
test = val;
//兩個線程都試圖將自己的私有變數val賦值給類私有靜態變數test
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new
UnatomicLong(-1));
Thread t2 = new Thread(new
UnatomicLong(0));
System.out.println(Long.toBinaryString(-1));
System.out.println(pad(Long.toBinaryString(0),
64));
t1.start();
t2.start();
long val;
while ((val = test) == -1
|| val == 0) {
//如果靜態成員test的值是-1或0,說明兩個線程操作沒有交叉
}
System.out.println(pad(Long.toBinaryString(val), 64));
System.out.println(val);
t1.interrupt();
t2.interrupt();
}
// prepend 0s to the string to make it the target
length
private static String pad(String s, int targetLength) {
int n = targetLength - s.length();
for (int x = 0; x < n; x++) {
s = "0" + s;
}
return s;
}
}
『肆』 java double型數據精確值問題
java中double類型數據是用64位來表示的,精度肯定是有限的,在需要更高精度的運算過程中,有兩種方法可供參考:1. 自己用超過64位來表示一個double類型,比如用100個byte[]來表示一個double(800bytes);這樣的話,double的加減乘除就需要自己實現一遍了。很多IT公司有這樣的面試題。2. 用java自帶的BigDecimal類可以方便做高精度的運算。(c++中是沒有BigDecimal這種方面的類的,所以只能用第一種方法)
『伍』 java double精度輸出問題
這里不能直接用System.out.println("%.6f",s);
java將print封裝成了三個輸出格式:
System.out.println(); 輸出後換行
System.out.printf(); 輸出帶指定格式的內容
System.out.print(); 直接列印,不換行
要實現精度控制,需要用第2中格式的輸出!
『陸』 一個關於JAVA中double精度誤差的問題,詳細及代碼問題如下
因為遞歸方法計算函數中的這句:
return Math.round(replace*10000)/10000.0;
每次遞歸的返回值都被你精確到萬分之一而四捨五入了,這樣會有累積誤差
而循環方法計算的就沒有這個問題,直到最後才四捨五入一次。
正確做法是return Math.round(replace*10000)/10000.0;改成return replace;
遞歸完全返回後,對結果進行一次四捨五入。
『柒』 java中double型如何控制有效數字輸出位數或精度
java中 double 類型只是一個簡單類型,是不能其輸出位數及精度是固定的
可以利用其它方法進行位數輸出,如:
public static void main(String[] args) {
// 1. 使用 String.format() 方法
double data = 11.8982389283293;
System.out.println(String.format("%.2f", data));
// 2. 使用 printf 輸出
System.out.printf("%.2f", data);
// 3. 使用 DecimalFormat 對象格式化
DecimalFormat format = new DecimalFormat("#.00");
System.out.println(format.format(data));
}
『捌』 java 轉化為double類型後精度
http://blog.csdn.net/yinan9/article/details/17283081
『玖』 java中整數型的精度是幾位
都是用二進制存的,整形的就是沒有二進制小數,只保留整數位,你兌換成二版進制就清楚了權;
數據在機器的存儲中有兩種方式定點型和浮點型,看每個機器的設定 。而且是以二進制形式存儲,比如浮點型以階符,階碼;符號位,小數位;具體可以參考計算機組成原理的前兩章。通俗解釋就是把二進制轉換成小數*2的n次方,n就是階碼,小數就是後邊的。
『拾』 java和c語言的double精度問題
java 3.5802468781999996
C 3.5802468781999996 (printf("%.16lf", a+b);
你說不一樣,是因為C默認輸出6位小數吧。 printf("%lf", a+b);
這個精度是由計算機本身決定的,double類型的精度,在目前機器上的精度范圍是15-16位小數之間。