<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><span class="vcard"><a class="email" href="mailto:mclow.lists@gmail.com" title="Marshall Clow (home) <mclow.lists@gmail.com>"> <span class="fn">Marshall Clow (home)</span></a>
</span> changed
              <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - duration_cast has rounding bug converting long double seconds to long long nanoseconds"
   href="http://llvm.org/bugs/show_bug.cgi?id=20537">bug 20537</a>
        <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">Status</td>
           <td>NEW
           </td>
           <td>RESOLVED
           </td>
         </tr>

         <tr>
           <td style="text-align:right;">Resolution</td>
           <td>---
           </td>
           <td>INVALID
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - duration_cast has rounding bug converting long double seconds to long long nanoseconds"
   href="http://llvm.org/bugs/show_bug.cgi?id=20537#c3">Comment # 3</a>
              on <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED INVALID - duration_cast has rounding bug converting long double seconds to long long nanoseconds"
   href="http://llvm.org/bugs/show_bug.cgi?id=20537">bug 20537</a>
              from <span class="vcard"><a class="email" href="mailto:mclow.lists@gmail.com" title="Marshall Clow (home) <mclow.lists@gmail.com>"> <span class="fn">Marshall Clow (home)</span></a>
</span></b>
        <pre>(In reply to <a href="show_bug.cgi?id=20537#c0">comment #0</a>)
<span class="quote">> Converting from floating-point seconds to nanoseconds, there is a
> demonstrable rounding bug.  It looks like converting from floating-point
> seconds to integral nanoseconds uses division by 1e-9 instead of
> multiplication by 1e9 which causes rounding error when the floating-point
> storage is long double.</span >

I believe that you've misdiagnosed what's going on here.
There is no division going on in your example.

If you have access to the C++11 standard, get a copy of section 20.11.5.7/2 and
let's step through it.

    typedef std::chrono::duration<long double> T;
    T x = 1.31_s;    
    x += 20_ms;

//  Let CF be ratio_divide<Period, typename ToDuration::period>
    typedef std::ratio_divide<T::period, nanoseconds::period>::type CF;
    std::cout << typeid(CF).name() << "\n";  // std::ratio<1000000000l, 1l>

//  and CR be common_type<typename ToDuration::rep, Rep, intmax_t>::type
    typedef std::common_type<nanoseconds::rep, T::rep, intmax_t>::type CR;
    std::cout << typeid(CR).name() << "\n";  // long double

//  Looking at [time.duration.cast]/2, this falls under the second bullet
    auto res = static_cast<CR>(x.count() * static_cast<CR>(CF::num));
//  this prints '1329999999.9999999999'
    std::cout << std::fixed << std::setprecision(10) << res << std::endl;
//  this prints '1329999999'
    std::cout << static_cast<long long>(res) << std::endl;

//  this prints '1329999999 vs 1330000000 from 1.3300000000'
    std::cout << duration_cast<nanoseconds>(x).count() << " from " << x.count()
<< "\n";

I think that the problem here is that your "1.33" is not really "1.33", but
rather "1.329999999xxxxx", so that when it gets multiplied and converted to an
integral type, you get 1329999999.

In any case, I'm pretty sure that it's not a bug in libc++. Please re-open if
you disagree.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>