浮点高精求和(洛谷P2393题题解,弃坑Java拥抱C++)
題目要求
P2393題目鏈接
分析
這題實(shí)則是變態(tài)的大浮點(diǎn)加法,眾所周知的是浮點(diǎn)不精確,按照IEEE754來(lái)。
原先使用Java寫(xiě)的,但下面分析一下為什么不能用Java寫(xiě)。
這代碼本來(lái)是這么寫(xiě)的:
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ù),是空文件,連換行符都沒(méi)有……
我原本以為數(shù)據(jù)錯(cuò)了,可能有換行符的,就加了一個(gè)特判:
結(jié)果一樣的,真的惡心啊。
你用nextLine()或者readLine()沒(méi)用的,根本不行。
用任何Scanner都不能過(guò),只能用BufferedReader,但也沒(méi)什么頭緒,畢竟BufferedReader一般來(lái)說(shuō)只能讀取一行或者一個(gè)字符,都不合適。
想了很久,就琢磨出一個(gè)騷方法:
沒(méi)錯(cuò),先讀首字符,如果沒(méi)有就拜拜,打印0.00000,否則就拼接起來(lái)唄……
只過(guò)了第一個(gè),后5個(gè)還是WA:
下了一個(gè)數(shù)據(jù)6,震驚,被惡心到了,double拼起來(lái)必定不精確啊,一看確實(shí),誤差挺大。
我后來(lái)加上了strictfp關(guān)鍵詞,發(fā)現(xiàn)對(duì)double無(wú)效。(這個(gè)詞研究不深,但測(cè)過(guò)多次,盲猜是讓float按照IEEE754算,對(duì)double沒(méi)啥大用……)
突然靈機(jī)一動(dòng),高精?我上BigDecimal吧,高精沒(méi)毛病:
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é)果只能說(shuō)略有改觀吧:
測(cè)試點(diǎn)6和8過(guò)不去的,對(duì)比發(fā)現(xiàn)我們的BigDecimal算的過(guò)于精確了……比給的answer精確……
我瞬間心態(tài)爆炸……
讀到這里您也能想到我為了各種測(cè)試畫(huà)了多少時(shí)間和精力吧,居然不是不精確就是過(guò)精確。
偏偏Java沒(méi)有 long double 這回事,枯萎……
然后我棄坑Java,拾起C++,十行以?xún)?nèi)秒了這題。。。
一句題外話(huà)是:性能差距過(guò)大。
提示:洛谷的OJ基本面向中學(xué)信息學(xué)競(jìng)賽,所以C++是王道,你用Java人家不理你的,見(jiàn)好就收即可,嗯……
AC代碼(C++語(yǔ)言描述)
#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ǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的浮点高精求和(洛谷P2393题题解,弃坑Java拥抱C++)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Python】PyCharm中Matp
- 下一篇: C++空间分配器简述学习笔记