Skip to content

Precision loss over far smaller durations than 9 years #2

@lichendust

Description

@lichendust

While building a film and scoring tool that depends on this library, I ran into some odd precision issues on values far smaller than expected based on the claims of the library.

Initially I believed it was after repeated conversion back and forth between Timecode and time.Duration, but in fact the behaviour just occurs above certain arbitrary values per edit rate.

For a 24fps edit rate, the timestamp begins to drift by whole frames during the 375th hour — a lot less than 9 years.

This example shows a timecode gaining an extra frame immediately on creation —

package main

import "fmt"
import "time"

import lib "github.com/trimmer-io/go-timecode/timecode"

func main() {
    const DURATION = time.Hour * 375

    tc := lib.New(DURATION, lib.Rate24)

    fmt.Println(tc)
}
375:00:00:01

The problem occurs far earlier at higher edit rates, such as —

  • 60fps — 58th hour
  • 120fps — 28th hour

In theory, this shouldn't come up in most use-cases, but the precision claim is wildly overstated and anyone who might be using the library under the assumption of high-precision without questioning it may be surprised.


I was going to build a better example using a zero tc and adding 32,000,000 frames to it to show it coughing back up 32,000,001 from tc.Frame() but, while doing that I also discovered that AddFrames with a frame number greater than the existing frame count of the Timecode just clamps it to zero.

The negative result gate is implemented backwards; positive values greater than the base tc value are zero'd, and negative values are freely allowed to wrap around.

func main() {
    tc := lib.New(0, lib.Rate24)
    tc = tc.AddFrames(-1)
    fmt.Println(tc)
}
160127:59:21:11

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions