真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網站制作重慶分公司

go語言保留2位小數(shù) go 保留兩位小數(shù)

go使用decimal

在公司項目中看到關于錢的數(shù)據(jù)在接口展示、添加修改的各種情況下結構體中相應字段用的都是string類型。覺得不太合理,因此查閱了一些資料,整理如下。

在咸陽等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供成都網站建設、網站設計 網站設計制作按需網站制作,公司網站建設,企業(yè)網站建設,高端網站設計,成都營銷網站建設,外貿網站建設,咸陽網站建設費用合理。

在網上搜到一篇博客:

在程序計算中涉及到錢的時候,為什么要用Decimal而不是Float

博客中介紹,如果用float類型再轉為decimal類型時會造成精度丟失。轉為string后再轉為decimal則可以解決問題,保證精度??粗孟袷呛芡昝赖幕卮鹆宋蚁胍私獾膯栴},但仔細一看用的語言是python,于是我便親自試了下:

結果確實如此,但看版本是2.7,我懷疑是不是python2.7版本落后,因此存在問題,于是又換了python3,再次測試:

結論依然是一樣。好吧,證實了,對于python確實應該先轉為string再轉為decimal。

但是,python是這樣,難道go也是這樣嗎,于是我又開始了進一步測試:

go中decimal使用第三方庫

這里是直接用float64轉為decimal,并沒有通過string中轉,結果輸出如下:

乍一看,看著好像是精度丟失了似的,但是對比后我們發(fā)現(xiàn),float64和decimal前后都是一致的,也就是說float64轉為decimal之后,保持了原樣。那些看起來小數(shù)點后位數(shù)很多的結果,是因為float64浮點類型計算產生的問題,跟轉換并沒有關系。

為了驗證這一結論,我又寫了下面的測試:

不使用浮點類型相加,而用decimal類型相加,這樣輸出結果果然沒問題了:

因此我們可以得出結論:對于go語言,在把float轉換為decimal類型時,并不需要像python一樣通過string中轉,也依然可以保持精度。進一步,我們也可以想到上面的問題,對于錢,在結構體字段中,我們完全可以直接使用float類型,并不需要用string類型。而且好處時,使用float數(shù)值類型,無論對于前端還是后端,在進行數(shù)值范圍驗證的時候,會更方便,不必把string轉為float后再驗證了。

上面提到了decimal包,我們這里簡單看下,里面的常用的方法:

定義decimal的幾種方式:

decimal數(shù)值運算

比較:

我們再看下浮點精度運算不準確的原因,這篇文章講解的比較細

浮點精度(float、double)運算不精確的原因

精度運算不準確這是為什么呢?我們接下來就需要從計算機所有數(shù)據(jù)的表現(xiàn)形式二進制說起了。如果大家很了解二進制與十進制的相互轉換,那么就能輕易的知道精度運算不準確的問題原因是什么了。

接下來我們看一個簡單的例子 2.1 這個十進制數(shù)轉成二進制是什么樣子的。

落入無限循環(huán)結果為 10.0001100110011........ , 我們的計算機在存儲小數(shù)時肯定是有長度限制的,所以會進行截取部分小數(shù)進行存儲,從而導致計算機存儲的數(shù)值只能是個大概的值,而不是精確的值。從這里看出來我們的計算機根本就無法使用二進制來精確的表示 2.1 這個十進制數(shù)字的值,連表示都無法精確表示出來,計算肯定是會出現(xiàn)問題的。

1、為什么數(shù)值表示用decimal 不用double

2、在程序計算中涉及到錢的時候,為什么要用Decimal而不是Float

3、MySQL數(shù)據(jù)類型DECIMAL用法

4、浮點精度(float、double)運算不精確的原因

基礎知識 - Golang 中的格式化輸入輸出

【格式化輸出】

// 格式化輸出:將 arg 列表中的 arg 轉換為字符串輸出

// 使用動詞 v 格式化 arg 列表,非字符串元素之間添加空格

Print(arg列表)

// 使用動詞 v 格式化 arg 列表,所有元素之間添加空格,結尾添加換行符

Println(arg列表)

// 使用格式字符串格式化 arg 列表

Printf(格式字符串, arg列表)

// Print 類函數(shù)會返回已處理的 arg 數(shù)量和遇到的錯誤信息。

【格式字符串】

格式字符串由普通字符和占位符組成,例如:

"abc%+ #8.3[3]vdef"

其中 abc 和 def 是普通字符,其它部分是占位符,占位符以 % 開頭(注:%% 將被轉義為一個普通的 % 符號,這個不算開頭),以動詞結尾,格式如下:

%[旗標][寬度][.精度][arg索引]動詞

方括號中的內容可以省略。

【旗標】

旗標有以下幾種:

空格:對于數(shù)值類型的正數(shù),保留一個空白的符號位(其它用法在動詞部分說明)。

0 :用 0 進行寬度填充而不用空格,對于數(shù)值類型,符號將被移到所有 0 的前面。

其中 "0" 和 "-" 不能同時使用,優(yōu)先使用 "-" 而忽略 "0"。

【寬度和精度】

“寬度”和“精度”都可以寫成以下三種形式:

數(shù)值 | * | arg索引*

其中“數(shù)值”表示使用指定的數(shù)值作為寬度值或精度值,“ ”表示使用當前正在處理的 arg 的值作為寬度值或精度值,如果這樣的話,要格式化的 arg 將自動跳轉到下一個?!癮rg索引 ”表示使用指定 arg 的值作為寬度值或精度值,如果這樣的話,要格式化的 arg 將自動跳轉到指定 arg 的下一個。

寬度值:用于設置最小寬度。

精度值:對于浮點型,用于控制小數(shù)位數(shù),對于字符串或字節(jié)數(shù)組,用于控制字符數(shù)量(不是字節(jié)數(shù)量)。

對于浮點型而言,動詞 g/G 的精度值比較特殊,在適當?shù)那闆r下,g/G 會設置總有效數(shù)字,而不是小數(shù)位數(shù)。

【arg 索引】

“arg索引”由中括號和 arg 序號組成(就像上面示例中的 [3]),用于指定當前要處理的 arg 的序號,序號從 1 開始:

'[' + arg序號 + ']'

【動詞】

“動詞”不能省略,不同的數(shù)據(jù)類型支持的動詞不一樣。

[通用動詞]

v:默認格式,不同類型的默認格式如下:

布爾型:t

整 型:d

浮點型:g

復數(shù)型:g

字符串:s

通 道:p

指 針:p

無符號整型:x

T:輸出 arg 的類型而不是值(使用 Go 語法格式)。

[布爾型]

t:輸出 true 或 false 字符串。

[整型]

b/o/d:輸出 2/8/10 進制格式

x/X :輸出 16 進制格式(小寫/大寫)

c :輸出數(shù)值所表示的 Unicode 字符

q :輸出數(shù)值所表示的 Unicode 字符(帶單引號)。對于無法顯示的字符,將輸出其轉義字符。

U :輸出 Unicode 碼點(例如 U+1234,等同于字符串 "U+%04X" 的顯示結果)

對于 o/x/X:

如果使用 "#" 旗標,則會添加前導 0 或 0x。

對于 U:

如果使用 "#" 旗標,則會在 Unicode 碼點后面添加相應的 '字符'(前提是該字符必須可顯示)

[浮點型和復數(shù)型]

b :科學計數(shù)法(以 2 為底)

e/E:科學計數(shù)法(以 10 為底,小寫 e/大寫 E)

f/F:普通小數(shù)格式(兩者無區(qū)別)

g/G:大指數(shù)(指數(shù) = 6)使用 %e/%E,其它情況使用 %f/%F

[字符串或字節(jié)切片]

s :普通字符串

q :雙引號引起來的 Go 語法字符串

x/X:十六進制編碼(小寫/大寫,以字節(jié)為元素進行編碼,而不是字符)

對于 q:

如果使用了 "+" 旗標,則將所有非 ASCII 字符都進行轉義處理。

如果使用了 "#" 旗標,則輸出反引號引起來的字符串(前提是

字符串中不包含任何制表符以外的控制字符,否則忽略 # 旗標)

對于 x/X:

如果使用了 " " 旗標,則在每個元素之間添加空格。

如果使用了 "#" 旗標,則在十六進制格式之前添加 0x 前綴。

[指針類型]

p :帶 0x 前綴的十六進制地址值。

[符合類型]

復合類型將使用不同的格式輸出,格式如下:

結 構 體:{字段1 字段2 ...}

數(shù)組或切片:[元素0 元素1 ...]

映 射:map[鍵1:值1 鍵2:值2 ...]

指向符合元素的指針:{}, [], map[]

復合類型本身沒有動詞,動詞將應用到復合類型的元素上。

結構體可以使用 "+v" 同時輸出字段名。

【注意】

1、如果 arg 是一個反射值,則該 arg 將被它所持有的具體值所取代。

2、如果 arg 實現(xiàn)了 Formatter 接口,將調用它的 Format 方法完成格式化。

3、如果 v 動詞使用了 # 旗標(%#v),并且 arg 實現(xiàn)了 GoStringer 接口,將調用它的 GoString 方法完成格式化。

如果格式化操作指定了字符串相關的動詞(比如 %s、%q、%v、%x、%X),接下來的兩條規(guī)則將適用:

4。如果 arg 實現(xiàn)了 error 接口,將調用它的 Error 方法完成格式化。

5。如果 arg 實現(xiàn)了 string 接口,將調用它的 String 方法完成格式化。

在實現(xiàn)格式化相關接口的時候,要避免無限遞歸的情況,比如:

type X string

func (x X) String() string {

return Sprintf("%s", x)

}

在格式化之前,要先轉換數(shù)據(jù)類型,這樣就可以避免無限遞歸:

func (x X) String() string {

return Sprintf("%s", string(x))

}

無限遞歸也可能發(fā)生在自引用數(shù)據(jù)類型上面,比如一個切片的元素引用了切片自身。這種情況比較罕見,比如:

a := make([]interface{}, 1)

a[0] = a

fmt.Println(a)

【格式化輸入】

// 格式化輸入:從輸入端讀取字符串(以空白分隔的值的序列),

// 并解析為具體的值存入相應的 arg 中,arg 必須是變量地址。

// 字符串中的連續(xù)空白視為單個空白,換行符根據(jù)不同情況處理。

// \r\n 被當做 \n 處理。

// 以動詞 v 解析字符串,換行視為空白

Scan(arg列表)

// 以動詞 v 解析字符串,換行結束解析

Scanln(arg列表)

// 根據(jù)格式字符串中指定的格式解析字符串

// 格式字符串中的換行符必須和輸入端的換行符相匹配。

Scanf(格式字符串, arg列表)

// Scan 類函數(shù)會返回已處理的 arg 數(shù)量和遇到的錯誤信息。

【格式字符串】

格式字符串類似于 Printf 中的格式字符串,但下面的動詞和旗標例外:

p :無效

T :無效

e/E/f/F/g/G:功能相同,都是掃描浮點數(shù)或復數(shù)

s/v :對字符串而言,掃描一個被空白分隔的子串

對于整型 arg 而言,v 動詞可以掃描帶有前導 0 或 0x 的八進制或十六進制數(shù)值。

寬度被用來指定最大掃描寬度(不會跨越空格),精度不被支持。

如果 arg 實現(xiàn)了 Scanner 接口,將調用它的 Scan 方法掃描相應數(shù)據(jù)。只有基礎類型和實現(xiàn)了 Scanner 接口的類型可以使用 Scan 類方法進行掃描。

【注意】

連續(xù)調用 FScan 可能會丟失數(shù)據(jù),因為 FScan 中使用了 UnreadRune 對讀取的數(shù)據(jù)進行撤銷,而參數(shù) io.Reader 只有 Read 方法,不支持撤銷。比如:

請大大解決一條程序題~

//呵,再不合你題意,我還真是郁悶

#include stdio.h

#define MAX_ARRAY 10

Go_Shop()

{

int a[5][2]={{200701,25},{200702,40},{200703,50},{200704,80},{200705,102}};

int number[MAX_ARRAY][MAX_ARRAY];

int Num_flag=1;

int num,M_num,j,s;

int i=0;

int cost=0,Nn=0;

printf("請輸入商品編號(以0結束):");

scanf("%d",num);

printf("請輸入購買件數(shù):");

scanf("%d",M_num);

while(num)

{

number[i][0]=num;

number[i][1]=M_num;

i++;

printf("請輸入商品編號(以0結束):");

scanf("%d",num);

if(num!=0)

{

printf("請輸入購買件數(shù):");

scanf("%d",M_num);

}

}

printf("您所購買的商品編號 商品價格 商品件數(shù)\n");

for(j=0;j=i-1;j++)

{

Num_flag=0;

for(s=0;s=4;s++)

{

if(number[j][0]==a[s][0])

{

printf("%17d%10d%10d\n",a[s][0],a[s][1],number[j][1]);

cost+=a[s][1]*number[j][1];

Nn+=number[j][1];

Num_flag=1;

}

}

if(Num_flag==0)

printf("[%d]這個商品編號不存在!\n",number[j]);

}

printf("商品件數(shù)為:%d\n",Nn);

printf("總價格為:%d\n",cost);

printf("繼續(xù)嗎?(Y/N)");

return 0;

}

void main()

{

int Y_N_flag=0;

char SayY_N;

Go_Shop();

while(Y_N_flag!=-1)

{

switch(SayY_N=getchar())

{

case 'Y':

Go_Shop();

break;

case 'N':

Y_N_flag=-1;

printf("歡迎下次光臨!\n");

break;

}

}

}

運行結果:

請輸入商品編號(以0結束):200701

請輸入購買件數(shù):10

請輸入商品編號(以0結束):200704

請輸入購買件數(shù):16

請輸入商品編號(以0結束):255555

請輸入購買件數(shù):20

請輸入商品編號(以0結束):0

您購買的商品編號 商品價格 商品件數(shù)

200701 25 10

200704 80 16

〔255555〕這個商品編號不存在!

可購買商品件數(shù)為:26

總價格為:1530

繼續(xù)嗎?(Y/N):N

歡迎您下次光臨!

Press any key to continue


當前名稱:go語言保留2位小數(shù) go 保留兩位小數(shù)
網站鏈接:http://weahome.cn/article/doddhij.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部