как конвертировать int64-fixed-point в double?

0

Я использую int64 для хранения decimal значений. В финансовом отношении мне нужны "точные" значения, поэтому я должен использовать base 10 не base 2. У меня это глобально:

typedef int64_t myDecimal;
const int DECIMALS_GLOBAL = 10;

я "multiple" каждое значение до 10^10 Например

1 is 10000000000
0.001 is 10000000

Теперь мне нужно преобразовать myDecimal в double. Это звучит просто, я просто могу ((double) myDecValue)/10^10 но это рискованно, потому что довольно вероятно, что double не способен хранить "большие" значения int64. Поэтому я написал такую функцию:

int64_t posPow10_64[] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000,
100000000000,
1000000000000,
10000000000000,
100000000000000,
1000000000000000
};

double Utils::MyDecimalToDouble(myDecimal value) {
    int beforeDot = value / posPow10_64[DECIMALS_GLOBAL];
    return (double) beforeDot + ((double) (value - beforeDot * posPow10_64[DECIMALS_GLOBAL])) / posPow10_64[DECIMALS_GLOBAL];
}

Я думаю, что эта функция менее рискованна, потому что я отбрасываю двойное значащее меньшее значение, но эта функция выглядит очень сложной и, вероятно, медленной.

Что бы вы порекомендовали, моя проблема распространена, как конвертировать в двойную быстроту и безопасно?

  • 1
    это выглядит очень, очень плохой дизайн ....
  • 0
    @ MitchWheat почему? что бы вы порекомендовали для decimal в C ++?
Показать ещё 9 комментариев
Теги:

1 ответ

2

Что касается "довольно вероятно, что double не способен хранить" большой "int64", это зависит от того, означает ли вы точно. Поскольку вы используете десятичную неподвижную точку, большинство значений, которые вы имеете, не могут быть сохранены точно, если double тип реализации не будет десятичным (что в принципе может быть, в отличие от целых чисел, которые должны быть двоичными). Например, 0.2 не может быть сохранен точно с любым обычным double типом, потому что он не может быть точно выражен как сумма степеней 2.

Однако, если он не может быть сохранен точно, он не может быть сохранен точно, и никакое количество устройств интеллектуального преобразования не сможет обойти это.

Обычно double - это 64-битная плавающая точка IEEE с точностью до 52 бит и с диапазоном, большим, чем 64-битное целое число, поэтому величина не является проблемой.


Подводя итоги, вы можете просто сделать double(myDecValue)/10000000000 (обратите внимание, что 10^10 - это выражение bitlevel xor).

  • 0
    int64 находится в диапазоне от –9,223,372,036,854,775,808 до 9,223,372,036,854,775,807. Как вы думаете, я могу разыграть 9,223,372,036,854,775,807, чтобы doulbe не терял никакой информации? if (int64) (double) 9 223 372 036 854 775 807 == 9 223 372 036 854 775 807?
  • 0
    @javapowered: как уже упоминалось, вы не можете даже конвертировать 0.2 в double без потери информации (для обычной реализации C ++). очевидно, у вас есть два взаимоисключающих требования: (1) преобразовать в double и (2) не потерять информацию в любом случае. Затем вы должны отказаться от хотя бы одного требования.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню