我实施了@Tom Alsberg的建议(double
变体)。有注意事项(比较frac_t == uint32_t
和frac_t == uint64_t
的输出)。
#include <iomanip> // setw()
#include <iostream>
#include <limits>
typedef unsigned frac_t;
const frac_t FRACTIONS_PER_SECOND = std::numeric_limits<frac_t>::max();
template <class Uint>
Uint fraction2usec(Uint fraction) {
return static_cast<Uint>(fraction * 1e6/FRACTIONS_PER_SECOND + 0.5);
}
template <class Uint>
Uint usec2fraction(Uint usec) {
return static_cast<Uint>(usec/1e6 * FRACTIONS_PER_SECOND + 0.5);
}
int main(void) {
uintmax_t fractions[] = {
0, 1, 0x10c6, 0x10c6f7a0b5edull,
static_cast<uintmax_t>(FRACTIONS_PER_SECOND/2. + 0.5),
static_cast<uintmax_t>(FRACTIONS_PER_SECOND/4. + 0.5),
FRACTIONS_PER_SECOND,
FRACTIONS_PER_SECOND + 0x1ull,
};
const int w1 = 2*sizeof(uintmax_t) , w2 = 10;
for (size_t i = 0; i < (sizeof(fractions)/sizeof(*fractions)); ++i)
std::cout << std::hex << std::setw(w1) << fractions[i] << ": "
<< std::dec << std::setw(w2) << fraction2usec(fractions[i])
<< ", " << std::hex << std::setw(w1)
<< usec2fraction(fraction2usec(fractions[i])) << "\n";
}
输出(frac_t == uint32_t
):
0: 0, 0
1: 0, 0
10c6: 1, 10c7
10c6f7a0b5ed: 4294967297, 10c6f7a0b5ee
80000000: 500000, 80000000
40000000: 250000, 40000000
ffffffff: 1000000, ffffffff
100000000: 1000000, ffffffff
输出(frac_t == uint64_t
):
0: 0, 0
1: 0, 0
10c6: 0, 0
10c6f7a0b5ed: 1, 10c6f7a0b5ee
8000000000000000: 500000, 8000000000000000
4000000000000000: 250000, 4000000000000000
ffffffffffffffff: 1000000, 0
0: 0, 0
来源
2009-02-15 16:09:17
jfs
如果浮点中间不正常,但在64位整数是,为什么不乘以第一和然后呢? – mghie 2009-02-15 10:57:55
对,我正要补充一点,但后来我的脑海里想要实现32位整数缩放 – 2009-02-15 11:09:06