C++将SATOSHI(uint64_t)转换为不带浮点/双精度的BTC(string)

C++ Convert SATOSHI(uint64_t) to BTC (string) without float/double

本文关键字:string BTC 双精度 uint64 SATOSHI C++ 转换      更新时间:2023-10-16

我需要构建一个函数,该函数接受uin64_t(SATOSHI)并吐出一个具有BTC值的字符串。我被告知要在没有任何除法/浮点运算的情况下进行,所以应该涉及纯字符串操作。这是因为如果我去Satoshi/1BTC,我最终会得到一个很好的值,但无法正确地将其转换为字符串(由于四舍五入)

想不出如何做到这一点,知道:

uin64_t uiSatoshi = 1033468;
uint64_t uiOneBTC = 100000000;
std::string strBTC = "";

知道BTC有8位小数,如何从UiSatoshi构造strBTC。

尝试:

// SATOSHI TO STRING (for exchange)  
    int iSatoshi = 1033468;
    double dVal = (double)iSatoshi / (double)100000000;

    std::ostringstream out;
    out << std::setprecision(8) << dVal;
    std::string strOutput = out.str();
    printf("WRONG: %fn", dVal);
    printf("TEST: %sn", strOutput.data());

错误:0.010335测试:0.01033468

但当uiSatoshi的值为=101033468时,它失败了由于结果是圆形的:测试:1.0103347

我想避免做浮点运算,只需要用我的整数做一个字符串,加上前导零,把点放在需要的地方。

更新:答案张贴在这里:C++printf舍入?

一个简单的转换例程可以如下所示:

#include <iostream>
#include <string>
using namespace std;
string to_btc(uint64_t sat) {
  auto s = to_string(sat);
  if (s.length() < 8) {
    // Prefix with 0s
    s.insert(0, (8 - s.length()), '0');
    s.insert(0, "0.", 2);
  } else if (s.length() == 8) {
    s.insert(0, "0.", 2);
  } else {
    // Insert a '.' in the right place
    s.insert(s.length() - 8, 1, '.');
  }
  return s;
}
int main ()
{
  cout << to_btc(10346834567ULL) << endl;
  cout << to_btc(1034683456ULL) << endl;
  cout << to_btc(103468345) << endl;
  cout << to_btc(10346834) << endl;
  cout << to_btc(1034683) << endl;
  cout << to_btc(10368) << endl;
  cout << to_btc(1038) << endl;
  cout << to_btc(132) << endl;
  cout << to_btc(18) << endl;
  cout << to_btc(1) << endl;
  cout << to_btc(0) << endl;
}

不需要浮子,我并不是说这是完整的,可以生产,但我相信你可以彻底测试它,以检查它是否符合你的期望。它可以优化吗?可能,但我将把它作为一个练习。。。