2016-12-18 3 views
1

Ich denke der Titel sagt alles, aber lassen Sie mich ein wenig mehr hineingehen.Dezimalstunde zeigt 4 min 60 Sekunden nicht 5 Minuten

Ich speichere Dezimalstunden in einem DB alle 5 Minuten, während ein Benutzer meine App verwendet. Ich habe ein paar Probleme mit der Anzeige der richtigen Zeit für einige der 5 min Blöcke, in denen es 4 min und 60 Sekunden zeigt. Jeder 3. 5-Minuten-Block zeigt dies.

So wie etwas, dieses

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

Einige haben sogar n: 59 statt n: 00

Teil des Codes ist:

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

Irgendwelche Vorschläge, was ich tun könnte falsch?

+0

'floor (x)% 60' werden Sie nie 60 geben (oder vielleicht tut es für Punkte floating Versuchen Sie,' int' zu konvertieren, bevor Sie '%'?) Bitte zeigen Sie mehr von dem Code. Enthalten Sie auch, was der Wert von "decimalHour" für diese Testfälle war. – Thilo

+0

Wenn möglich, speichern Sie Ihre Dauer lieber als Sekunden (Ganzzahl) anstelle von Nachkommastellen (Fließkomma). – Thilo

+0

Verwende 'let mins = Int (floor (dezimalHour * 60))% 60' – shallowThought

Antwort

3

Binäre Gleitkommazahl kann nicht alle Zahlen genau darstellen, daher neigt Ihr Code zu Rundungsfehlern. Beispiel (Swift 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 

Die tatsächliche Anzahl in decimalHour gespeichert ist geringfügig kleiner als 1 + 5/60, und deshalb werden die Sekunden falsch berechnet.

(Beachten Sie auch, dass Sie nicht % mit Gleitkommazahlen in Swift 3 verwenden können, vergleichen What does "% is unavailable: Use truncatingRemainder instead" mean?.)

Wie bereits in den Kommentaren, ein besserer Ansatz wäre sein, die Dauer als eine ganze Zahl zu speichern (Anzahl der Sekunden).

Wenn das nicht möglich ist, runde die Gleitkommazahl nach a der Anzahl von Sekunden, und dann mit reiner ganzzahlige Arithmetik fortzusetzen. Beispiel (arbeitet mit Swift 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 
Verwandte Themen