我目前產生一個JavaScript驅動數學包,其重點四捨五入各種顯著數字(SF)但我已經運行成我掙扎的一個問題解決。舍入到有效數字 - 缺少零點
更多關於這個問題後,但首先給你一些背景。
該計劃的目的是選擇一個完全隨機數在一定範圍內,然後自動計算出該號碼的相關顯著數字;例如:
隨機數:0.097027
S.Fs:9, 7, 0, 2, 7
這裏是什麼,我產生了給你的直觀表示截圖:
正如您所看到的,一旦用戶選擇了他們的號碼,他們就有機會點擊四個獨立的'SF'按鈕查看分別呈現給1,2,3和4個S.F的隨機數。
對於每個SF(1-4)隨機數爲捨去,圍捕和四捨五入到X SF和下方的標尺給用戶一個更視覺呈現,以顯示爲什麼SF值已被程序選擇。
我已經爲此寫了絕大多數的代碼並進行了測試,到目前爲止數字已經出來了,我期待他們。 Well ...
在我給出的例子中(0.097027)
;正如你在我所包含的圖像上看到的那樣,4 S.F的數據是絕對正確的並且準確輸出。
當我點擊到3 SF按鈕,我希望看到以下內容:
隨機數:0.097027
3 SF圍捕/ DOWN/OFF:0.0970
但是,我實際得到的是:
隨機數:0.097027
3 S.F圓形向上/向下/關閉:0.097
該程序未顯示附加零。這是我的程序中以數字結尾的一個數字的完美示例,在這種情況下,零是非常重要的,必須顯示。
數據通常是正確的,但在正確的時間輸出顯着的零似乎存在問題。我研究了toFixed(x)
方法,如果我分配toFixed(4)
,我會得到正確的所需輸出,但是因爲我的數字是每次隨機生成的,所以它們的範圍可以從5個數字的長度(例如, 89.404
高達> 10,例如`0.000020615。
因此,看起來方法需要是靈活/動態的,例如,toFixed(n)
預先運行一個函數來確定究竟需要多少尾隨零?
這裏是從我目前的解決方案的一些關鍵摘錄供大家參考:
function generateNum() {
do {
genNumber = Math.random() * Math.pow (10, randomRange(-5, 5));
//Round
genNumber = roundToNSF(genNumber, 5, 0);
// This number must contain >1 digit which is 1 to 9 inclusive otherwise we may have e.g. 100. Rounding 100
}
while (!countNonZero(genNumber) || genNumber < 1E-05 || genNumber == 0);
//Round
genNumber = roundToNSF(genNumber, 5, 0);
genNumber = String(genNumber);
genNumber = Number(genNumber);
}
//----------------------------------------------------------------------------
function randomRange(min, max) {
/**
* Returns a random integer between min (inclusive) and max (inclusive)
* Using Math.round() will give you a non-uniform distribution!
*/
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//---------------------------------------------------------------------------
//Click SF3 Button to reveal the data
function showSF3() {
//Remove any CSS properties on the buttons from previous use
removeButtonCSS();
document.getElementById('SFRounded').style.display = "block";
document.getElementById('scale').style.display = "block";
document.getElementById("SF3").className = document.getElementById("SF3").className + "buttonClick"; // this removes the blue border class
//Clear text
deleteRounded();
deleteScale();
//Run calculation
calculateAnswer();
//alert(genNumber.toFixed(4));
for (i = 3; i < 4; i++)
{
//Add The new data
sfRoundedTextBlock = document.getElementById('SFRounded');
//alert(downArray[i].toFixed(4));
//Data output to HTML.
sfRoundedTextBlock.innerHTML = sfRoundedTextBlock.innerHTML + '<p><strong>Number: </strong></br>' + String(genNumber) +
'</br>' + '<strong>Rounded down to ' + i + ' SF:</br></strong>' + downArray[i] + '</br>' +
'<strong>Rounded up to ' + i + ' SF:</br></strong>' + upArray[i] + '</br><strong>Rounded off to ' + i + ' SF:</br></strong>'
+ roundedArray[i] + '</br>' + '(See the scale below for why we choose <strong>' + roundedArray[i] + '</strong> as the rounded off value.)</p>';
}
}
//----------------------------------------------------------------------
var roundedArray = [];
var upArray = [];
var downArray = [];
var temp;
function calculateAnswer() {
//Clear Arrays
roundedArray = [];
upArray = [];
downArray = [];
// Work out the answer:
for (i = 0; i < 4; i++) {
var nSF = i + 1;
// Round OFF ...
temp = roundToNSF(genNumber, nSF, 0);
// We actually have to do this twice ...
roundedArray[nSF] = roundToNSF(temp, nSF, 0);
// Round UP ...
upArray[nSF] = roundToNSF(genNumber, nSF, 1);
// Round DOWN ...
downArray[nSF] = roundToNSF(genNumber, nSF, -1);
// e.g. x = 0.0098 rounded to 1SF is 0.010 initially (take the log of 0.0098 and try it!).
};
};
//-------------------------------------------------------------------------
//Globals
var aNumber;
var digits;
var way;
function roundToNSF(aNumber, digits, way){
// Round a number to n significant figures (can use roundToNDP provided we know how many decimal places):
if (way == undefined) { way = 0; }; // default is round off
if (aNumber !=0) {
if (aNumber > 0)
{
z = log10(aNumber);
}
else
{
z = log10(-aNumber);
};
z = Math.floor(z);
var nDP = digits - z - 1; // Rounding to nDP decimal places is equivalent to rounding to digits significant figures ...
var roundedNumber = roundToNDP(aNumber, nDP, way);
}
else {
roundedNumber = aNumber; // Number is zero ...
};
return Number(roundedNumber);
};
//---------------------------------------------------------------------------------
更新:
我還在繼續,試圖找到一個解決方案這個問題和我最近採取的一種方法是將我的隨機生成的數字轉換爲可搜索的字符串變量,然後使用indexOf(".")
命令查找小數點(dp)的位置。
然後我搜遍了我的號碼,從dp的位置開始查找一個重要的非零數字[1-9]的第一個實例。
var genNumber = 0.097027;
var rString = String(genNumber);
var positionofDP = rString.indexOf(".");
var regexp = /[1-9]/;
var positionofNonZero = Number(rString.search(regexp, positionofDP)); // Output would be '5'
我已經這才得以進一步瞄準我的搜索,以確定我的第一個顯著數量是否在它之後立即位數任何「問題」零。
如果有,然後我設置一個布爾變量爲'true',然後在一個單獨的函數中創建我的舍入/關閉/向上數字的更多文本字符串,所以我可以物理地選擇添加'0 '到現有數字字符的末尾。
這種方法對我個人來說在孤立的情況下工作,但隨機數字長度從5-12位長,但仍不能處理所有情況。
也許我需要創建一個動態的toFixed(i)
函數?任何想法都會受到歡迎。