亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

什么是一種與Math.floorMod()完全相同但使用浮點數而不是整數的方法?

什么是一種與Math.floorMod()完全相同但使用浮點數而不是整數的方法?

慕容森 2022-08-17 15:31:46
下面是 Math.floorMod(x, 5) 的一組輸入和輸出作為示例。int x; inputs: x = -15 | -14 | -13 | -12 | -11     -10 | -09 | -08 | -07 | -06     -05 | -04 | -03 | -02 | -01     +00 | +01 | +02 | +03 | +04*     +05 | +06 | +07 | +08 | +09     +10 | +11 | +12 | +13 | +14outputs:    *+00 | +01 | +02 | +03 | +04需要明確的是,列 1 中的所有輸入都會導致列 1 中的輸出,依此類推。我也希望能夠用花車做到這一點,但我一直找不到任何東西來幫助我。這個想法是,所有浮點都應該映射到和(第二個參數)吃豆人風格之間的浮點盤上。Math.relevantMethod()0y
查看完整描述

2 回答

?
梵蒂岡之花

TA貢獻1900條經驗 獲得超5個贊

溶液

我花了一段時間來開發算法并解決所有問題,但事實就是如此。我配音.floatMod()


double floatMod(double x, double y){

    // x mod y behaving the same way as Math.floorMod but with doubles

    return (x - Math.floor(x/y) * y);

}

下面是一個浮點模型(x, 2.0d) 的輸入和輸出表作為示例。(我修復了整潔的輕微舍入錯誤。


double x;


inputs:

x = -4.0 | -3.6 | -3.2 | -2.8 | -2.4

    -2.0 | -1.6 | -1.2 | -0.8 | -0.4

    +0.0 | +0.4 | +0.8 | +1.2 | +1.6*

    +2.0 | +2.4 | +2.8 | +3.2 | +3.6

    +4.0 | +4.4 | +4.8 | +5.2 | +5.6


outputs:

   *+0.0 | +0.4 | +0.8 | +1.2 | +1.6

下面是一些其他示例。


floatMod(0.1f, 1f);     //returns: 0.1

floatMod(1.1f, 1f);     //returns: 0.100000024 aka 0.1 + 0.000000024

floatMod(2.1f, 1f);     //returns: 0.099999905 aka 0.1 - 0.000000095

floatMod(10000.1f, 1f); //returns: 0.099609375 aka 0.1 - 0.000390625


floatMod(0.1d, 1d);     //returns: 0.1

floatMod(1.1d, 1d);     //returns: 0.10000000000000009 aka 0.1 + 0.00000000000000009

floatMod(2.1d, 1d);     //returns: 0.10000000000000009 aka 0.1 + 0.00000000000000009

floatMod(10000.1d, 1d); //returns: 0.10000000000036380 aka 0.1 - 0.00000000000036380

算法說明

如果您對算法的工作原理感興趣,我會盡力解釋。讓我們使用上面的例子。x - Math.floor(x/y) * yfloatMod(x, 2.0d)


首先,取 x 的可能值的以下數行:


                                ●------------------------○

       |                        |                        |                        |

-2.4 -2.0 -1.6 -1.2 -0.8 -0.4 +0.0 +0.4 +0.8 +1.2 +1.6 +2.0 +2.4 +2.8 +3.2 +3.6 +4.0 +4.4

垂直線之間的空間表示在兩個方向上并排堆疊的長度 y 塊。填充圓表示包含,而空心圓表示排他性,上面所示的圓包含由虛線表示的塊 0。


接下來,(在本例中為 y = 2.0)在數字線 x 上采用給定位置,并給出塊的數量。因此,2.0 是塊 0 的末尾和塊 1 的開頭,因此 2.0/y = 1.0。x/y


我們會說 x/y = c;


1.0/y → 0.5c 作為 1.0 是半塊

3.2/y → 1.6c

-2.4/y → -1.2c

等。


接下來,意味著無論我們處于哪個區塊中,都將c減少到所述區塊的開頭。換句話說,哪一個是x?Math.floor(c)


0.5c → 0.0c

1.6c → 1.0c

-1.2c → -2.0c


接下來,它將結果再次乘以y,以x的形式將其取回。


0.0c * y → 0.0

1.0c * y → 2.0

-2.0c * y → -4.0


最后,它只取這個值并計算x離它有多遠,就像x離它所在的塊的開頭有多遠一樣?


另一種看待它的方式:它需要減去x中的額外塊,所以它從塊0中計算出x向前或向后多少塊,并刪除該數量。這使其保持在 0 和 y 的范圍內。


1.0 - 0.0 → 1.0

3.2 - 2.0 → 1.2

-2.4 - -4.0 → 1.6


(呃...好吧,在寫完了算法的大部分解釋之后,我意識到有一種方法可以簡化它。在我這樣做之后,我意識到它實際上與floorMod算法完全相同,只是使用浮點數。我在這里表現得像某種學者,他發現了萬物的統一理論,而我所做的只是從我眼皮底下的東西多走了一步。我保證,我絞盡腦汁從頭開始開發它。


我最初的算法在某一時刻變得非?;靵y。我仍然很高興我寫了這篇文章,因為我相信這是很好的信息,而且很有趣。-Math.floor(x/y) * y + x


查看完整回答
反對 回復 2022-08-17
?
喵喔喔

TA貢獻1735條經驗 獲得超5個贊

對模量使用浮點 esp 的一個問題是,您會看到明顯的表示錯誤。你最好做的是舍入結果或計算,這樣你就能得到理智的結果。一個簡單的方法是假設你只需要N個精度數字,例如6。


public static double floorMod(double x, double y) {

    return Math.floorMod(Math.round(x * 1e6), Math.round(y * 1e6)) / 1e6;

}

對于上面的例子,你得到


floorMod(0.1f, 1f);     //returns: 0.1

floorMod(1.1f, 1f);     //returns: 0.1

floorMod(2.1f, 1f);     //returns: 0.1

floorMod(10000.1f, 1f); //returns: 0.099609 due to the limits of float.


floorMod(0.1d, 1d);     //returns: 0.1

floorMod(1.1d, 1d);     //returns: 0.1

floorMod(2.1d, 1d);     //returns: 0.1

floorMod(10000.1d, 1d); //returns: 0.1

另一種方法是指定精度


public static double floorMod(double x, double y, double precision) {

    double factor = Math.round(1 / precision);

    return Math.floorMod(Math.round(x * factor), Math.round(y * factor)) / factor;

}


floorMod(10000.1f, 1f, 0.1); // returns 0.1


查看完整回答
反對 回復 2022-08-17
  • 2 回答
  • 0 關注
  • 133 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號