我一直在用 JavaScript 撰寫一個腳本,以根據各種型別的資料繪制圖形圖表和曲線,這些資料基于每個類別的不同度量值,例如 g、kg、噸的重量或 C° 或 F 的溫度等。我留下了選擇縮放比例讓用戶手動輸入他們想要覆寫的區間,這部分就完成了。
現在我想為自動縮放添加一個選項,并根據最小值和最大值生成一個最佳間隔,而最優我的意思是一個很好的間隔讀數。資料因類別而異,這里是所有案例:
{min=0, max=45 } => [0,100] // min= 0 so begin = 0 and 45 is 2 digits so end = 100
{min=0, max=123 } => [0,200] // begin = 0 , 123 is 3 digits end= 200
{min=-45, max=201 } => [-100,300]
{min=-1, max=1 } => [-1,1]
{min=0.01, max=0.06 } => [0,0.1]
{min=-0.009, max=-0.004 } => [-0.01,0]
{min=-0.8, max=0.9 } => [-1,1]
{min=-335, max=-12 } => [-400,0]
... and so on
所以我從使用獲取數字的想法開始
// if min != 0 && max>=min && max!=0
// rounding
begin=Math.floor(min);
end=Math.ceil(max);
// then if end is positive
// getting the endvalue meaning getting the 10 exponent
threshold = Math.pow(10,Math.floor(Math.log10(end)));
// loop while
while( end % threshold !=0) end ;
// else do the rest the same and care for negative values
這樣它就可以作業,但并非在所有情況下,如果有人想改進,請成為我的客人,謝謝。
uj5u.com熱心網友回復:
一些備注:
Math.log10(0)是 -Infinity,所以當end是 0 時要小心。- 當最小值的閾值與最大值的閾值不同時,我假設您要應用這兩者中的最大值。
while回圈效率不高。相反,您可以將數字除以閾值,然后再乘以。
這是調整后的代碼。我添加了你的測驗用例。對于第一個它報告了一個差異,但我認為邏輯應該是 45 舍入到 50,而不是 100:
function getThreshold(n) {
return n && Math.pow(10, Math.floor(Math.log10(Math.abs(n))));
}
function getRange({min, max}) {
min = Math.floor(min);
max = Math.ceil(max);
let threshold = Math.max(getThreshold(min), getThreshold(max));
min = min && Math.round(Math.floor(min / threshold) * threshold);
max = max && Math.round(Math.ceil(max / threshold) * threshold);
return [min, max];
}
let tests = [
[{min:0, max:45 }, [0,100]],
[{min:0, max:123 }, [0,200]],
[{min:-45, max:201 }, [-100,300]],
[{min:-1, max:1 }, [-1,1]],
[{min:0.01, max:0.6 }, [0,1]],
[{min:-0.8, max:0.9 }, [-1,1]],
[{min:-335, max:-12 }, [-400,0]],
];
for (let [input, expected] of tests) {
let result = getRange(input);
if (JSON.stringify(result) !== JSON.stringify(expected)) {
console.log("got", ...result, "expected", ...expected);
}
}
console.log("all done");
正如評論中所討論的,對于小范圍(如 [0.00193, 0.00221]),最好不要要求輸出由整數組成,但可以是 [0.001, 0.003] 之類的東西。
在這種情況下,您可以使用:
function getThresholdPower(n) {
return n && Math.floor(Math.log10(Math.abs(n)));
}
function getRange({min, max}) {
let thresholdPower = Math.max(getThresholdPower(min), getThresholdPower(max));
let threshold = 10 ** Math.abs(thresholdPower);
// Deal with negative powers differently
// to avoid floating point precision issues
if (thresholdPower < 0) {
min = min && Math.floor(min * threshold) / threshold;
max = max && Math.ceil(max * threshold) / threshold;
} else {
min = min && Math.floor(min / threshold) * threshold;
max = max && Math.ceil(max / threshold) * threshold;
}
return [min, max];
}
let tests = [
[{min:0, max:45 }, [0,100]],
[{min:0, max:123 }, [0,200]],
[{min:-45, max:201 }, [-100,300]],
[{min:-1, max:1 }, [-1,1]],
[{min:0.01, max:0.6 }, [0,1]],
[{min:-0.8, max:0.9 }, [-1,1]],
[{min:-335, max:-12 }, [-400,0]],
];
for (let [input, expected] of tests) {
let result = getRange(input);
if (JSON.stringify(result) !== JSON.stringify(expected)) {
console.log("got", ...result, "expected", ...expected);
}
}
console.log("all done");
顯然,這個片段報告了與預期輸出的更多偏差。
uj5u.com熱心網友回復:
好吧,這并不完全像您想要的那樣,但這會標準化為 10 的冪。
function normalize_to_10_power(value, is_down) {
if (is_down) {
if (value > 0) {
return Math.pow(10, Math.floor(Math.log10(value)))
}
if (value < 0) {
return -Math.pow(10, Math.ceil(Math.log10(-value)))
}
} else {
if (value > 0) {
return Math.pow(10, Math.ceil(Math.log10(value)))
}
if (value < 0) {
return -Math.pow(10, Math.floor(Math.log10(-value)))
}
}
return 0
}
function normalize_range(min, max) {
return [
normalize_to_10_power(min, true),
normalize_to_10_power(max)
]
}
var tests = [
[{ min: 0, max: 45 }, [0, 100]],
[{ min: 0, max: 123 }, [0, 200]],
[{ min: -45, max: 201 }, [-100, 300]],
[{ min: -1, max: 1 }, [-1, 1]],
[{ min: 0.01, max: 0.6 }, [0, 1]],
[{ min: -0.009, max: -0.004 }, [0, 1]],
[{ min: -0.8, max: 0.9 }, [-1, 1]],
[{ min: -335, max: -12 }, [-400, 0]],
];
for (let [input, expected] of tests) {
var result = normalize_range(input.min, input.max);
console.log("input: ", input, "result: ", result);
}
注意 {min=-0.009, max=-0.004 } => [-0.01,0] 應該是 [-0.01, -0.001] (如果我們按照這個演算法去)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/496609.html
標籤:javascript 算法 数学
上一篇:無法理解為什么演算法作業得這么快
