2016-12-18 4 views
1

私はタイトルがそれをすべて言っていると思いますが、私はもう少しそれに行きましょう。小数点時間は4分60秒ではなく5分を示します

ユーザーが自分のアプリケーションを使用している間に、5分ごとにDBに10進数の時間を格納しています。私は、4分と60秒を示すという点で、5分のブロックのいくつかに正しい時間を表示するのに少し問題があります。 3分5秒ごとのブロックがこれを示しています。

だから、この

4:60 
10:00 
15:00 
19:60 

のようなものがいくつかさえ持っN:59の代わりに、nは:コードの00

一部は次のとおりです。

let hours = Int(floor(decimalHour)) 
let mins = Int(floor(decimalHour * 60) % 60) 
let secs = Int(floor(decimalHour * 3600) % 60) 

私がやって何ができるか任意の提案違う?

+0

'階(X)%60'はあなたに60を与えることはありません(または多分それは浮動小数点の場合と' '%を行う前にint''に変換してみ? )コードの詳細を表示してください。 'decimalHour'の値がこれらのテストケースのためにあったものも含めます。 – Thilo

+0

可能であれば、分数時間(浮動小数点数)ではなく秒(整数)として期間を保存してください。 – Thilo

+0

'let mins = Int(floor(decimalHour * 60))%60'を使用します。 – shallowThought

答えて

3

バイナリ浮動小数点数はすべて数字 を正確に表すことができないため、コードでは丸め誤差が発生しやすくなります。 例(スイフト2):

let decimalHour = 1.0 + 5.0/60.0 

print(decimalHour.debugDescription) // 1.0833333333333333 
print(floor(decimalHour * 3600)) // 3899.0 

let hours = Int(floor(decimalHour)) 
let mins = Int(floor(decimalHour * 60) % 60) 
let secs = Int(floor(decimalHour * 3600) % 60) 

print(hours, mins, secs) // 1 5 59 
decimalHour

に格納された実際の数が1 + 5/60よりもわずかに小さいので、秒を誤って計算されます。

(また、あなたがWhat does "% is unavailable: Use truncatingRemainder instead" mean?を比較し、浮動小数点数スウィフト3で で%を使用することはできませんのでご注意。)

すでにコメントで述べたように、より良いアプローチは、(整数として期間を保存するために だろう秒数)。次いで

それが不可能な場合、 へラウンド浮動小数点数の秒数と純粋整数 演算を続けます。例(スウィフト2 + 3で動作します):

let decimalHour = 1.0 + 5.0/60.0 

let totalSeconds = lrint(decimalHour * 3600) // round to seconds 
let hours = totalSeconds/3600 
let mins = (totalSeconds % 3600)/60 
let secs = totalSeconds % 60 

print(hours, mins, secs) // 1 5 0 
関連する問題