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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

浮点高精求和(洛谷P2393题题解,弃坑Java拥抱C++)

發(fā)布時間:2025/3/15 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浮点高精求和(洛谷P2393题题解,弃坑Java拥抱C++) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目要求

P2393題目鏈接

分析

這題實(shí)則是變態(tài)的大浮點(diǎn)加法,眾所周知的是浮點(diǎn)不精確,按照IEEE754來。
原先使用Java寫的,但下面分析一下為什么不能用Java寫。

這代碼本來是這么寫的:

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);double sum = 0.0;String[] array = scanner.nextLine().trim().split("\\s+");scanner.close();for (String s : array) {sum += 1000000 * Double.parseDouble(s);}System.out.printf("%.5f", sum/1000000);} }

但結(jié)果是這樣的:

你們敢想象為什么RE?我下了數(shù)據(jù),是空文件,連換行符都沒有……
我原本以為數(shù)據(jù)錯了,可能有換行符的,就加了一個特判:

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);double sum = 0.0;String line = scanner.nextLine();if ("".equals(line)) {System.out.println("0.00000");return;}String[] array = line.trim().split("\\s+");scanner.close();for (String s : array) {sum += 1000000 * Double.parseDouble(s);}System.out.printf("%.5f", sum/1000000);} }

結(jié)果一樣的,真的惡心啊。
你用nextLine()或者readLine()沒用的,根本不行。
用任何Scanner都不能過,只能用BufferedReader,但也沒什么頭緒,畢竟BufferedReader一般來說只能讀取一行或者一個字符,都不合適。
想了很久,就琢磨出一個騷方法:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class Main {public strictfp static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));double sum = 0.0;int firstRead = reader.read();if (firstRead == -1) {System.out.println("0.00000");return;}firstRead -= 48;String line = firstRead + reader.readLine();String[] array = line.trim().split("\\s+");reader.close();for (String s : array) {sum += 1000000 * Double.parseDouble(s);}System.out.printf("%.5f", sum/1000000);} }

沒錯,先讀首字符,如果沒有就拜拜,打印0.00000,否則就拼接起來唄……
只過了第一個,后5個還是WA:

下了一個數(shù)據(jù)6,震驚,被惡心到了,double拼起來必定不精確啊,一看確實(shí),誤差挺大。

我后來加上了strictfp關(guān)鍵詞,發(fā)現(xiàn)對double無效。(這個詞研究不深,但測過多次,盲猜是讓float按照IEEE754算,對double沒啥大用……)

突然靈機(jī)一動,高精?我上BigDecimal吧,高精沒毛病:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigDecimal; import java.math.RoundingMode;public class Main {public strictfp static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));BigDecimal sum = new BigDecimal(0).setScale(5, RoundingMode.HALF_EVEN);;int firstRead = reader.read();if (firstRead == -1) {System.out.println("0.00000");return;}firstRead -= 48;String line = firstRead + reader.readLine();String[] array = line.trim().split("\\s+");reader.close();for (String s : array) {sum = sum.add(new BigDecimal(Double.parseDouble(s)));}System.out.printf("%.5f", sum);} }

結(jié)果只能說略有改觀吧:

測試點(diǎn)6和8過不去的,對比發(fā)現(xiàn)我們的BigDecimal算的過于精確了……比給的answer精確……
我瞬間心態(tài)爆炸……
讀到這里您也能想到我為了各種測試畫了多少時間和精力吧,居然不是不精確就是過精確。
偏偏Java沒有 long double 這回事,枯萎……

然后我棄坑Java,拾起C++,十行以內(nèi)秒了這題。。。

一句題外話是:性能差距過大。

提示:洛谷的OJ基本面向中學(xué)信息學(xué)競賽,所以C++是王道,你用Java人家不理你的,見好就收即可,嗯……

AC代碼(C++語言描述)

#include<cstdio> long double result, temp; int main() {while((scanf("%Lf", &temp)) != EOF) {result += temp * 1000000;}printf("%.5Lf", result / 1000000);return 0; } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的浮点高精求和(洛谷P2393题题解,弃坑Java拥抱C++)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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