web-dev-qa-db-ja.com

Lua:数値を丸めてから切り捨てる

数値を切り上げてから切り捨てる(切り上げ後に小数点以下の桁を削除する)ための最も効率的な方法はどれですか?

たとえば、decimalが0.5を超える場合(つまり、0.6、0.7など)、切り上げてから切り捨てます(ケース1)。それ以外の場合は、切り捨てます(ケース2)

for example:
232.98266601563 => after rounding and truncate = 233 (case 1)
232.49445450000 => after rounding and truncate = 232 (case 2)
232.50000000000 => after rounding and truncate = 232 (case 2)
18
user1624552

Luaには組み込みのmath.round()関数はありませんが、次のことができます:print(math.floor(a+0.5))

25
Ola M

整数以外の10進数で丸めるのに役立つトリックは、フォーマットされたASCIIテキストを介して値を渡し、_%f_フォーマット文字列を使用して必要な丸めを指定することです。例

_mils = tonumber(string.format("%.3f", exact))
_

exactの任意の値を0.001の倍数に丸めます。

math.floor()またはmath.ceil()のいずれかを使用する前後のスケーリングでも同様の結果が得られますが、Edgeケースの処理に関する期待に応じて詳細を正しく取得するのは難しい場合があります。これはstring.format()の問題ではないというわけではありませんが、「期待される」結果を生成するために多くの作業が行われています。

10の累乗以外の倍数に丸めるには、引き続きスケーリングが必要であり、依然としてすべてのトリッキーなエッジケースがあります。表現が簡単で、安定した動作を行うアプローチの1つは、

_function round(exact, quantum)
    local quant,frac = math.modf(exact/quantum)
    return quantum * (quant + (frac > 0.5 and 1 or 0))
end
_

frac(および場合によってはexactの符号)の正確な条件を調整して、必要なEdgeケースを取得します。

11
RBerteig

負の数もサポートするには、これを使用します:

function round(x)
  return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
8
ggVGc

任意の桁数(定義されていない場合は0)に丸める方法は次のとおりです。

function round(x, n)
    n = math.pow(10, n or 0)
    x = x * n
    if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end
    return x / n
end
3
toma91

半整数を正しく処理するには、math.ceil(a-0.5)にする必要があります

3

不正な丸め(端を切り取る)の場合:

function round(number)
  return number - (number % 1)
end

必要に応じて、これを拡張して丸めることができます。

function round(number)
  if (number - (number % 0.1)) - (number - (number % 1)) < 0.5 then
    number = number - (number % 1)
  else
    number = (number - (number % 1)) + 1
  end
 return number
end

print(round(3.1))
print(round(math.pi))
print(round(42))
print(round(4.5))
print(round(4.6))

推測される結果:

334255

2
Hastumer

RBerteigによる上記の応答が好きです:mils = tonumber(string.format("%.3f", exact))。関数呼び出しに拡張し、精度値を追加しました。

function round(number, precision)
   local fmtStr = string.format('%%0.%sf',precision)
   number = string.format(fmtStr,number)
   return number
end
1
Dan