簡體   English   中英

將數字四舍五入為 3 的倍數

[英]round numbers back to multiples of 3

我處於需要執行以下操作的情況:

if n = 0 or 1 or 2; return 0;
if n = 3 or 4 or 5; return 3;
if n = 6 or 7 or 8; return 6;
if n >= 9; return 9

我有以下工作正常的代碼。

var adjustNumberOfProducts = function(number) {
    var output = 0;
    switch(number) {
        case 0:
        case 1:
        case 2:
            output = 0;
            break;
        case 3:
        case 4:
        case 5:
            output = 3;
            break;
        case 6:
        case 7:
        case 8:
            output = 6;
            break;
        default:
            output = 9
            break;
    }
    return output;
}

我想知道是否有更優化(更快執行)的方法來做到這一點。

如果您追求原始速度,那么某種查找可能就是您想要的; 但是,通常的規則適用:使用分析器。

想到的查找類似於錯誤:

// DOES NOT WORK: 0 is falsy in JavaScript
var adjustNumberOfProducts = function (number) {
    return [0, 0, 0, 3, 3, 3, 6, 6, 6][number] || 9
}

但是由於 0 在 JavaScript 中是假的,我們可以使用 TJ Crowder 的(有趣的,不完全嚴肅的)“調整”:

var adjustNumberOfProducts = function (number) {
    return ([1, 1, 1, 4, 4, 4, 7, 7, 7][number] || 10) - 1
}

存在巨大的可讀性損失,許多程序員在實際代碼中看到這一點時會徹底畏縮(我認為“我的眼睛!”可能是現代反應。)

我認為需要進行 jsperf 測試來將這種邪惡的方法與您的 switch 語句和Math.min(number - (number% 3),9)技術進行映射。 我會使用一些 asm.js 技術,例如與零進行按位或運算來強制整數數學運算,看看這是否有幫助(盡管可能沒有)。

當然,你可以這樣做:

var adjustNumberOfProducts = function(number) {

    return Math.min(number - (number% 3),9);
}

您將除法的余數減去 3,使其成為 3 的倍數,然后取 9 之間的最小值作為更高的值

您可以使用一些簡單的數學運算來獲得此輸出:

 function adjust( number ) { return Math.min(Math.floor(number / 3) * 3, 9); } for ( var i = 0; i < 10; i++ ) document.write('For '+ i +': '+ adjust(i) + '<br>');

編輯:處理 9 的最大情況。

編輯:關於速度的說明。

雖然上面的代碼在每次調用adjust應用了更多的操作,但它的執行路徑更少。 switch語句有 9 種不同的執行路徑供編譯器考慮,而單個數學流可以編譯成更快的本機代碼(使用 JIT 編譯器)

只需使用i < 9 ? i - i % 3 : 9 i < 9 ? i - i % 3 : 9得到你的值。

 var i; for (i = 0; i < 16; i++) { document.write(i + ' ' + (i < 9 ? i - i % 3 : 9) + '<br>'); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM