0

My problem is a wrong result. I have a function this function has a distance and a time. The result I want to achieve is calculating running speed.

function runningPace(distance, time) {
  let result = time.replace(":", ".")
  let fl = parseFloat(result)
  let calc = fl / distance
  let num = calc.toFixed(2) + ''
  if(num.length === 1) {
    num = num + '.00'
  }
  let rep = num.replace('.', ':')
  console.log(distance, time, result, fl, calc, rep, num)
  
  return rep;
}

console.log(runningPace(5, '25:00')) // '5:00'
console.log(runningPace(4.99, '22:32')) // '4:30'

I wrote such a function. Sorry for the naming, I'll fix it when I get it fixed.

When I test this code, the output is:

expected '4:47' to equal '4:30'

'4:30' => four minute thirty second

How can I find a solution? Thanks everyone in advance.

  • 2
    `'0:59'` probably should not become the number `0.59`. There are 60 seconds in a minute, not 100 – evolutionxbox Feb 11 '22 at 23:45
  • 1
    I don't think you can just replace `:` with `.` and then convert it to number. Seconds and minutes are base 60, while converting it to a number using parseFloat assumes base 10. – Terry Feb 11 '22 at 23:45
  • May you also explain why you're expecting `4.47` to be `4.30`? – evolutionxbox Feb 11 '22 at 23:48
  • I think such a result is expected in the case because I am making a time-based query. @evolutionxbox – Kayra Berk Tuncer Feb 11 '22 at 23:49
  • 1
    @Kayra `1 min 30 sec` is equal to `1.5 minutes`. – evolutionxbox Feb 11 '22 at 23:50
  • '4:30' => four minute thirty second. i want to receive '4:30' @MisterJojo – Kayra Berk Tuncer Feb 12 '22 at 00:00
  • 1
    Split the time at `:`. Convert each part to an integer. Divide the second part by 60, and add it to the first part. That converts the time to minutes. – Barmar Feb 12 '22 at 00:01
  • 1
    So `4:30` becomes `4 + 30/60` which is `4.5` – Barmar Feb 12 '22 at 00:03
  • 2
    And as ever: floating point division _is not clean decimal division_ because floating point precision is not decimal. There are tons of decimal fractions that are literally impossible to encode as floating point values (like the value 0.1, which [cannot be represented](https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/) using floats). If you run into division oddities, your first port of call (if you never read it before) is ["What Every Computer Scientist Should Know About Floating-Point Arithmetic"](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Mike 'Pomax' Kamermans Feb 12 '22 at 00:09
  • @Mike'Pomax'Kamermans That's as true as ever, but not really relevant here since we're dealing with measurements of time and distance. It's fine to treat them as binary fractions, and using a decimal type wouldn't help since neither a decimal fraction nor a binary fraction can precisely represent 1/60. – David Conrad Feb 12 '22 at 00:39
  • Indeed, but working with integers where possible so you don't have float weirdness "at all" makes things a lot easier, as Barmar commented. – Mike 'Pomax' Kamermans Feb 12 '22 at 00:48

1 Answers1

1

convert anything in seconds:

function runningPace(dist, time)
  {
  let 
    [ mn, sc ] = time.split(':').map(Number)
  , fl         = Math.floor(((mn *60) + sc) / dist)
    ;
  sc = fl % 60
  mn = (fl - sc) / 60

  return `${mn}:${(sc<9)?'0'+sc:sc}`
}

console.log(runningPace( 5,    '25:00'))  // 5:00
console.log(runningPace( 4.99, '22:32'))  // 4:30
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40