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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于浮点数计算时的精度问题

發(fā)布時(shí)間:2025/3/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于浮点数计算时的精度问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

那個(gè)有問題的縮略圖生成的方法發(fā)布之后,短短半天就有很多朋友響應(yīng),其中指出了不少方法中的不少問題,有些也是我沒有意識到的。果然集體的智慧是無窮的,一段代碼在許多人的眼皮底下經(jīng)過,想留有bug也不容易。不過,我在這里只能談一下我寫那篇文章的本意了,我認(rèn)為那篇文章中最主要的問題是,在計(jì)算圖片尺寸時(shí)沒有處理好浮點(diǎn)數(shù)計(jì)算的精度問題。

為了凸現(xiàn)主要邏輯,我把之前那個(gè)方法中計(jì)算圖片尺寸的代碼單獨(dú)抽取成一個(gè)方法:

public static void GetThumbnailSize(int originalWidth, int originalHeight,int desiredWidth, int desiredHeight,out int newWidth, out int newHeight) {// If the image is smaller than a thumbnail just return itif (originalWidth <= desiredWidth && originalHeight <= desiredHeight){newWidth = originalWidth;newHeight = originalHeight;return;}// scale down the smaller dimensionif ((decimal)desiredWidth / originalWidth < (decimal)desiredHeight / originalHeight){decimal desiredRatio = (decimal)desiredWidth / originalWidth;newWidth = desiredWidth;newHeight = (int)(originalHeight * desiredRatio);}else{decimal desiredRatio = (decimal)desiredHeight / originalHeight;newHeight = desiredHeight;newWidth = (int)(originalWidth * desiredRatio);} }

我們通過簡單的代碼試驗(yàn)一下:

int newWidth, newHeight;GetThumbnailSize(200, 200, 100, 100, out newWidth, out newHeight); Console.WriteLine("{0}, {1}", newWidth, newHeight);GetThumbnailSize(300, 300, 100, 100, out newWidth, out newHeight); Console.WriteLine("{0}, {1}", newWidth, newHeight);

得到的結(jié)果是:

100, 100 99, 100

第一個(gè)結(jié)果自然沒有問題,但是在第二個(gè)結(jié)果中為什么是99而不是100?為此,我們再通過以下的代碼來觀察一番:

ratio: 0.3333333333333333333333333333 new value: 99.99999999999999999999999999 to int: 99

可見,雖然使用了decimal,精度已經(jīng)非常高的,但是在經(jīng)過了一除一乘,它還是沒有恢復(fù)到最精確值。雖然一直說要注意浮點(diǎn)數(shù)計(jì)算時(shí)的精度問題,但是對于這個(gè)問題許多朋友往往只是理解到“不能直接兩個(gè)浮點(diǎn)數(shù)相等”,包括我自己的第一印象。但事實(shí)上,從上面的結(jié)果也可以看出,把一個(gè)浮點(diǎn)數(shù)直接轉(zhuǎn)換成整形,它便是使用了“去尾”而不是“四舍五入”的方法。因此,雖然newValue的值無比接近100,但是在強(qiáng)制去尾后它還是變成了99。

如果要在原來的方法中改變這個(gè)問題,最簡單的方法可能是把最后的強(qiáng)制轉(zhuǎn)型替換成Math.Round方法。Math.Round方法使用四舍五入,應(yīng)該能夠解決問題。不過如果只是這樣的話收獲不大,我們再仔細(xì)想想,應(yīng)該如何做到盡可能的精確。

兩個(gè)浮點(diǎn)數(shù)相除可能會喪失精度,但如果是乘法操作,在一般情況下精度是不會丟失的,除非發(fā)生了溢出的話,或者小數(shù)位數(shù)太多。因此在計(jì)算過程中為了保持精度,我們應(yīng)該盡可能的做乘法,而不是作除法。例如以下的判斷:

if ((decimal)desiredWidth / originalWidth < (decimal)desiredHeight / originalHeight)

其實(shí)最好改寫成“等價(jià)”的乘法操作(假設(shè)沒有溢出):

if (desiredWidth * originalHeight < desiredHeight * originalWidth)

同理,如果可以的話,在作計(jì)算的時(shí)候,也最好先乘再除:

if (desiredWidth * originalHeight < desiredHeight * originalWidth) {newWidth = desiredWidth;newHeight = (int)Math.Round((decimal)originalHeight * desiredWidth / originalWidth); } else {newHeight = desiredHeight;newWidth = (int)Math.Round((decimal)originalWidth * desiredHeight / originalHeight); }

這么做,我們就避免了使用scaleRatio這個(gè)已經(jīng)喪失部分精度的值來參與計(jì)算,這樣1 * 3 / 3便可以等于1,而不像1 / 3 * 3等于0.99…。因此,最終我們CreateThumbnail的代碼便修改為:

/// <summary> /// Creates a thumbnail from an existing image. Sets the biggest dimension of the /// thumbnail to either desiredWidth or Height and scales the other dimension down /// to preserve the aspect ratio /// </summary> /// <param name="imageStream">stream to create thumbnail for</param> /// <param name="desiredWidth">maximum desired width of thumbnail</param> /// <param name="desiredHeight">maximum desired height of thumbnail</param> /// <returns>Bitmap thumbnail</returns> public Bitmap CreateThumbnail(Bitmap originalBmp, int desiredWidth, int desiredHeight) {// If the image is smaller than a thumbnail just return itif (originalBmp.Width <= desiredWidth && originalBmp.Height <= desiredHeight){return originalBmp;}int newWidth, newHeight;// scale down the smaller dimensionif (desiredWidth * originalBmp.Height < desiredHeight * originalBmp.Width){newWidth = desiredWidth;newHeight = (int)Math.Round((decimal)originalBmp.Height * desiredWidth / originalBmp.Width);}else{newHeight = desiredHeight;newWidth = (int)Math.Round((decimal)originalBmp.Width * desiredHeight / originalBmp.Height);}// This code creates cleaner (though bigger) thumbnails and properly// and handles GIF files better by generating a white background for// transparent images (as opposed to black)// This is preferred to calling Bitmap.GetThumbnailImage()Bitmap bmpOut = new Bitmap(newWidth, newHeight);using (Graphics graphics = Graphics.FromImage(bmpOut)){graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;graphics.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);graphics.DrawImage(originalBmp, 0, 0, newWidth, newHeight);}return bmpOut; }

當(dāng)然,在前文中很多朋友指出的其他一些問題也很有道理,例如:

  • 沒有做參數(shù)校驗(yàn)。
  • 直接返回源圖片的做法讓方法的含義不同。
  • 經(jīng)過計(jì)算后newWidth和newHeight可能為0。

例如還有朋友提出對GIF的處理不很妥當(dāng)?shù)鹊取绻衅渌敕ǖ脑?#xff0c;也可以繼續(xù)討論。或者,你也來分享一下代碼或工作中發(fā)現(xiàn)的問題?

from:?http://blog.zhaojie.me/2009/11/precision-of-float-point-calculation.html

總結(jié)

以上是生活随笔為你收集整理的关于浮点数计算时的精度问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 久久亚洲综合国产精品99麻豆精品福利 | 久久精品国产一区二区电影 | av无码av天天av天天爽 | 日本少妇18p | 亚洲黄色小说图片 | 免费成人视屏 | 亚洲婷婷在线观看 | www.999热| 人人爱爱人人 | 国产一区二区三区黄片 | 黄色.com | 国产三级精品视频 | 视屏一区| 国产三级在线播放 | 99re6热在线精品视频播放 | 色综合图片 | 夜夜春影院 | 国产一级网站 | 女人又爽又黄免费女仆 | 亚洲黄在线观看 | 欧美日本一区二区三区 | 九九色网 | 北条麻妃青青久久 | 久久精品这里只有精品 | 美女黄色一级片 | 五月的婷婷 | 国产成人无码AA精品区 | 手机av在线免费观看 | av在线免费播放网站 | 永久免费在线播放 | 国内自拍av| 日韩淫| 久久久久久无码精品人妻一区二区 | 国产鲁鲁视频在线观看特色 | 精品亚洲国产成av人片传媒 | 韩国久久久久 | 日本大奶子视频 | 成人午夜淫片100集 伊人久久国产 | 性久久久久久久久 | 在线视频中文 | aa片在线观看视频在线播放 | 影音先锋啪啪资源 | 三上悠亚 电影 | 免费福利在线视频 | 免费久久精品 | 污导航在线观看 | 国产在线一区二 | 亚一区二区 | 奇米影视中文字幕 | 捆绑调教视频网站 | 99热这里精品 | 亚洲黄视频 | 日韩av不卡在线播放 | a级黄色小视频 | mm视频在线观看 | 麻豆疯狂做受xxxx高潮视频 | 成人av电影在线观看 | 女人被狂躁c到高潮喷水电影 | 欧美视频免费看欧美视频 | 玖玖视频网 | 亚洲午夜精品一区二区三区他趣 | wwwwxxxx国产| 成年人香蕉视频 | 中国美女洗澡免费看网站 | 二区影院| 蜜桃久久一区二区三区 | 亚洲国产精品欧美久久 | 国产精品一区二区无码对白 | 亚洲国产成人精品久久 | 激情欧美一区二区三区精品 | caoporen超碰| 在线视频观看免费 | 成人av一区二区三区 | 午夜在线一区二区三区 | 日韩一级二级三级 | 久久青青热 | 久久蜜臀精品av | 99精品在线视频观看 | 欧美三级少妇高潮 | 日日操狠狠干 | 国产精品99久久久久久www | 蜜桃99视频一区二区三区 | 日韩精品福利在线 | 国产一级一级片 | 欧美激情中文字幕 | jizz中文字幕| 中文字幕一区二区三区不卡 | 五月婷婷激情视频 | 欧美亚洲精品在线 | 成人做爰www免费看视频网站 | 国产精品免费视频一区二区三区 | 免费黄视频网站 | 国产wwwxxx| 快色网站 | 亚洲日本三级 | 96精品视频在线观看 | 玉丸(双性调教) | 亚洲一区二区三区久久久成人动漫 | 中文字幕在线视频网 |