2017-10-25 80 views
5

Jak zrobić rational_cast<int64_t> z zaokrągleniem?doładowanie rational_cast z zaokrągleniem?

Obecnie robię hack tak:

boost::rational<int64_t> pts = ..., time_base = ...; 
int64_t rounded = std::llround(boost::rational_cast<long double>(pts/time_base)); 

Ale chciałbym, aby móc to zrobić „prawidłowo” bez angażowania zmiennoprzecinkowych.

+0

Wh w jakich typach są one zaangażowane? W szczególności 'pts' i' time_base' – sehe

+0

@sehe: Są to 'boost :: rational ' – ronag

Odpowiedz

1

Zaokrąglanie jest z natury stratne.

Najszybszy hack, który przychodzi do głowy jest po prostu za pomocą wbudowanego zachowania (co jest floor -ing lub trunc -ing wynik) z przesunięciem o połowę:

Live On Coliru

#include <iostream> 
#include <fstream> 
#include <boost/rational.hpp> 

int main() { 
    using R = boost::rational<int64_t>; 
    for (auto den : {5,6}) { 
     std::cout << "---------\n"; 
     for (auto num : {1,2,3,4,5,6}) { 
      R pq(num, den); 
      std::cout << num << "/" << den << " = " << pq << ": " 
         << boost::rational_cast<int64_t>(pq + R(1,2)) << "\n"; 
     } 
    } 
} 

Drukuje

--------- 
1/5 = 1/5: 0 
2/5 = 2/5: 0 
3/5 = 3/5: 1 
4/5 = 4/5: 1 
5/5 = 1/1: 1 
6/5 = 6/5: 1 
--------- 
1/6 = 1/6: 0 
2/6 = 1/3: 0 
3/6 = 1/2: 1 
4/6 = 2/3: 1 
5/6 = 5/6: 1 
6/6 = 1/1: 1