Skip to main content
27 of 39
added 310 characters in body
Οurous
  • 8.1k
  • 1
  • 16
  • 38

Cobra

class Trig
    const mod as float = 0.0174532925199433f
    var time as System.Diagnostics.Stopwatch = System.Diagnostics.Stopwatch()
    var file as String[] = File.readAllLines('trig.in')
    var input as float[] = float[](1)
    var sin_out as float[] = float[](1)
    var cos_out as float[] = float[](1)
    var tan_out as float[] = float[](1)
    def main
        .compute(0)
        .time.reset
        .input = .sin_out = .cos_out = .tan_out = float[](.file.length)
        for num, line in .file.numbered, .input[num] = float.parse(line)
        .time.start
        for num in .input.length, .compute(num)
        .time.stop
        for num in .file.length, .file[num] = (.sin_out[num].toString('0.000000E+0') + ' ' + .cos_out[num].toString('0.000000E+0') + ' ' + .tan_out[num].toString('0.000000E+0'))
        File.writeAllLines('trig.out', .file)
        print .time.elapsed
    def compute(index as int)
        degrees as float = .input[index]
        #for angles > 360, insert `degrees %= 360` here
        .cos_out[index] = cos as float = .cos(degrees)
        if degrees % 180, .sin_out[index] = sin as float = Math.sqrt(1 - (cos * cos)) * (((degrees - 180) * -1) / Math.abs(degrees - 180))
        else, .sin_out[index] = sin as float = 0
        .tan_out[index] = sin / cos
    def cos(degrees as float) as float
        if degrees % 180 <> 90
            rad as float = degrees * .mod
            two as float = rad * rad
            cos as float = 1
            cos -= (rad *= rad) / 2
            cos += (rad *= two) / 24
            cos -= (rad *= two) / 720
            cos += (rad *= two) / 40320
            cos -= (rad *= two) / 3628800
            cos += (rad *= two) / 479001600
            cos -= (rad *= two) / 87178291200
            cos += (rad *= two) / 20922789888000
            cos -= (rad *= two) / 6402373705728000
            cos += (rad *= two) / 2432902008176640000
            cos -= (rad *= two) / 1124000727777607680000f
            cos += (rad *= two) / 620448401733239439360000f
            cos -= (rad *= two) / 403291461126605635584000000f
            cos += (rad *= two) / 304888344611713860501504000000f
            return cos
        else, return 0

Compile it with cobra filename -turbo. Although if you can install Xamarin Studio and use this plugin, it'll provide times that are 2%-5% faster than even the -turbo flag. I'm not sure why.

The output is now 100% accurate to the specified number of sigfigs,
and is as fast as the inbuilt functions (but more accurate).

Tests: AMD FX6300 @5.1GHz

  • The 360 * 10000 test used by the C answer runs in 430ms (vs 190ms)

  • The 4-entry test used by the Python and Java answers runs in 0.4µs (vs 30µs, 3µs)

  • The 1000 random angle test used by the Fortran answer runs at 100ns per angle (vs 10µs)

Οurous
  • 8.1k
  • 1
  • 16
  • 38