まず第一に、皆さんに感謝します。これらのスニペットを共有しないと大変なことになります。
私の付加価値は、次のスニペットです(完全な実装については以下を参照してください)
parseFloat(number.toPrecision(precision))
たとえば、数値が 10000 で精度が 2 の場合、number.toPrecision(precision)
'1.0e+4' になりますが、parseFloat
指数表記を理解することに注意してください。
また、信じられないかもしれませんが、Math.pow
上記の対数を使用したアルゴリズムは、テスト ケースformatNumber(5, 123456789)
で実行すると、Mac (ノード v12) では成功しましたが、Windows (ノード v10) では上昇し、エラーが発生しました。奇妙だったので、上記の解決策にたどり着きました。
最後に、この投稿で提供されたすべてのフィードバックを利用して、これが決定的な実装であることがわかりました。次の内容のformatNumber.jsファイルがあるとします。
/**
* Format number to significant digits.
*
* @param {Number} precision
* @param {Number} number
*
* @return {String} formattedValue
*/
export default function formatNumber (precision, number) {
if (typeof number === 'undefined' || number === null) return ''
if (number === 0) return '0'
const roundedValue = round(precision, number)
const floorValue = Math.floor(roundedValue)
const isInteger = Math.abs(floorValue - roundedValue) < Number.EPSILON
const numberOfFloorDigits = String(floorValue).length
const numberOfDigits = String(roundedValue).length
if (numberOfFloorDigits > precision) {
return String(floorValue)
} else {
const padding = isInteger ? precision - numberOfFloorDigits : precision - numberOfDigits + 1
if (padding > 0) {
if (isInteger) {
return `${String(floorValue)}.${'0'.repeat(padding)}`
} else {
return `${String(roundedValue)}${'0'.repeat(padding)}`
}
} else {
return String(roundedValue)
}
}
}
function round (precision, number) {
return parseFloat(number.toPrecision(precision))
}
テストにテープを使用する場合、ここにいくつかの基本的なテストがあります
import test from 'tape'
import formatNumber from '..path/to/formatNumber.js'
test('formatNumber', (t) => {
t.equal(formatNumber(4, undefined), '', 'undefined number returns an empty string')
t.equal(formatNumber(4, null), '', 'null number return an empty string')
t.equal(formatNumber(4, 0), '0')
t.equal(formatNumber(4, 1.23456789), '1.235')
t.equal(formatNumber(4, 1.23), '1.230')
t.equal(formatNumber(4, 123456789), '123500000')
t.equal(formatNumber(4, 1234567.890123), '1235000')
t.equal(formatNumber(4, 123.4567890123), '123.5')
t.equal(formatNumber(4, 12), '12.00')
t.equal(formatNumber(4, 1.2), '1.200')
t.equal(formatNumber(4, 1.234567890123), '1.235')
t.equal(formatNumber(4, 0.001234567890), '0.001235')
t.equal(formatNumber(5, 123456789), '123460000')
t.end()
})