J'ai besoin de convertir une grande (trop grande pour les types de données intégrés) String à une chaîne avec une représentation décimale de sa représentation. Par exemple: Je suis actuellement en utilisant actuellement le C ++ Bigint Classe < / a> qui offre un moyen très simple d'y parvenir (mais est uniquement GPL): p> existe un moyen simple de faire cette conversion sans une bibliothèque arithmétique de tiers? Ou pouvez-vous recommander une alternative gratuite (non GPL) avec une simplicité similaire (l'efficacité n'est pas pertinente)? P> P>
3 Réponses :
std :: istringstream (shex) >> std :: hex >> sdec; p>
Malheureusement, cela ne semble pas fonctionner, SDec Obtenir est défini sur la même valeur que SHEX.
Avez-vous testé l'exemple d'entrée et de sortie fournis dans la question?
Oui, une chaîne hexagonale plus courte ("std :: istringstream (" 2a ") >> std :: hex >> sdec") donne le même comportement.
@FLAVIO: Je demandais Ashirius.
Vous pouvez utiliser cette fonction pour convertir un caractère hexadé en un caractère décimal: que vous pouvez l'utiliser pour convertir une chaîne: P> void HexStrToCharStr(const char* hexStr, unsigned char* decStr, int n)
{
unsigned char d_ch;
for(int i=0; i<n; i++)
{
Hex2Char(hexStr+2*i, d_ch);
decStr[i] = d_ch;
}
}
Cela ne me donnerait qu'une matrice avec les valeurs décimales de chaque caractère dans la chaîne hexagonale, mais je dois convertir la chaîne entière en un numéro. L'ajout de toutes les valeurs n'est pas possible car le résultat final sera trop important pour les entiers réguliers.
OK, voici une classe de convertisseur de base générique. J'ai écrit la mise en œuvre initiale en C # et convertit ceci maintenant en C ++. C'est .NET Les origines peuvent toujours briller. N'hésitez pas à l'utiliser comme vous le voyez.
Vous pouvez l'utiliser comme ceci: p> La sortie sera la suivante: p> La classe n'est pas limitée aux chiffres hexagonales, mais se traduira entre n'importe quelle base, en utilisant n'importe quel codage de chiffres de base. P> construit une nouvelle instance BaseConverter. La classe se traduit entre les nombres représentés dans une base de numéro source em> à une base de numéro em> cible em>. P>
Le constructeur prend deux arguments em> string em> pour spécifier les symboles à utiliser pour les bases de la source et de la cible. Le premier caractère de la chaîne a une valeur 0 em>, la 2e a une valeur 1 em>, etc. Exemple: Les symboles d'une base d'un nombre octal sont typiquement convertit nombre convertit un numéro décimal non signé sur la base du numéro cible. P> li>
convertit un numéro dans le système de numéro de source en une décimale non signée int em>. Fonctions de commodité Fonctions de retour des instances de API H2>
BASECONVERTERTER :: BASECONVERTER STD STD :: STR STR STD & SOURCEBaseSet, const STD :: String & TargeBbseset); Code> P>
"01234567" code>, et pour hexadécimal
"0123456789ABCDEF" code>. Tout caractère ASCII imprimable peut être utilisé pour un symbole, de sorte que vous puissiez par exemple. Utilisez
"OI" code> (au lieu de
"01" code>) pour un système binaire. p>
"0123456789Abcdef" code> pas em> ne pas em> décodage hexadécimal numéros à l'aide de caractères majuscules. p> li>
std :: string basoconverter :: convert strong> (STD :: Valeur de chaîne) const; code>
std :: string basoconverter :: convert strud> (const stdd :: string et valeur, taille_t Mindigits) const; code> p> p> p> P>
valeur code> dans la base de numéro de source dans la base du numéro cible et renvoie le résultat. La 2e surcharge prend un paramètre supplémentaire
Mindigits code> pour spécifier le nombre minimum de chiffres dans le résultat. La valeur renvoyée sera rembourrée par Prepending Zero ou plus de symboles ayant une valeur 0 em> dans la base de numéro de cible. P> li>
std :: string Baseconverter :: Fromdecimal strong> (valeur Int non signée) const; code>
Std :: String Baseconverter :: Fromdecimal STRUT> (Valeur Int non signée, Taille_T Mindigits) Const; Code>
P>
non signé int basoconverter :: todecimal strong> (STD :: Valeur de chaîne) const; code> p> p>
statique const Baseconverter &
Statique Const Baseconverter & Baseconverter :: Binarintodecimalconverter Strong> (); Code>
Statique Const BaseConverter & Baseconverter :: Decimaltohexconverter Strong> (); Code>
Statique Const BaseConverter & BasEconverter :: HextoDecimalconverter Strong> (); Code>
P>
Baseconverter Code> Convient pour convertir entre les bases de numéro commun.
BASECONVERTERTER.H: H2>
// Arbitrary precision base conversion by Daniel Gehriger <gehriger@linkcad.com>
#include "BaseConverter.h"
#include <stdexcept>
#include <algorithm>
const char* BaseConverter::binarySet_ = "01";
const char* BaseConverter::decimalSet_ = "0123456789";
const char* BaseConverter::hexSet_ = "0123456789ABCDEF";
BaseConverter::BaseConverter(const std::string& sourceBaseSet, const std::string& targetBaseSet)
: sourceBaseSet_(sourceBaseSet)
, targetBaseSet_(targetBaseSet)
{
if (sourceBaseSet.empty() || targetBaseSet.empty())
throw std::invalid_argument("Invalid base character set");
}
const BaseConverter& BaseConverter::DecimalToBinaryConverter()
{
static const BaseConverter dec2bin(decimalSet_, binarySet_);
return dec2bin;
}
const BaseConverter& BaseConverter::BinaryToDecimalConverter()
{
static const BaseConverter bin2dec(binarySet_, decimalSet_);
return bin2dec;
}
const BaseConverter& BaseConverter::DecimalToHexConverter()
{
static const BaseConverter dec2hex(decimalSet_, hexSet_);
return dec2hex;
}
const BaseConverter& BaseConverter::HexToDecimalConverter()
{
static const BaseConverter hex2dec(hexSet_, decimalSet_);
return hex2dec;
}
std::string BaseConverter::Convert(std::string value) const
{
unsigned int numberBase = GetTargetBase();
std::string result;
do
{
unsigned int remainder = divide(sourceBaseSet_, value, numberBase);
result.push_back(targetBaseSet_[remainder]);
}
while (!value.empty() && !(value.length() == 1 && value[0] == sourceBaseSet_[0]));
std::reverse(result.begin(), result.end());
return result;
}
std::string BaseConverter::Convert(const std::string& value, size_t minDigits) const
{
std::string result = Convert(value);
if (result.length() < minDigits)
return std::string(minDigits - result.length(), targetBaseSet_[0]) + result;
else
return result;
}
std::string BaseConverter::FromDecimal(unsigned int value) const
{
return dec2base(targetBaseSet_, value);
}
std::string BaseConverter::FromDecimal(unsigned int value, size_t minDigits) const
{
std::string result = FromDecimal(value);
if (result.length() < minDigits)
return std::string(minDigits - result.length(), targetBaseSet_[0]) + result;
else
return result;
}
unsigned int BaseConverter::ToDecimal(std::string value) const
{
return base2dec(sourceBaseSet_, value);
}
unsigned int BaseConverter::divide(const std::string& baseDigits, std::string& x, unsigned int y)
{
std::string quotient;
size_t lenght = x.length();
for (size_t i = 0; i < lenght; ++i)
{
size_t j = i + 1 + x.length() - lenght;
if (x.length() < j)
break;
unsigned int value = base2dec(baseDigits, x.substr(0, j));
quotient.push_back(baseDigits[value / y]);
x = dec2base(baseDigits, value % y) + x.substr(j);
}
// calculate remainder
unsigned int remainder = base2dec(baseDigits, x);
// remove leading "zeros" from quotient and store in 'x'
size_t n = quotient.find_first_not_of(baseDigits[0]);
if (n != std::string::npos)
{
x = quotient.substr(n);
}
else
{
x.clear();
}
return remainder;
}
std::string BaseConverter::dec2base(const std::string& baseDigits, unsigned int value)
{
unsigned int numberBase = (unsigned int)baseDigits.length();
std::string result;
do
{
result.push_back(baseDigits[value % numberBase]);
value /= numberBase;
}
while (value > 0);
std::reverse(result.begin(), result.end());
return result;
}
unsigned int BaseConverter::base2dec(const std::string& baseDigits, const std::string& value)
{
unsigned int numberBase = (unsigned int)baseDigits.length();
unsigned int result = 0;
for (size_t i = 0; i < value.length(); ++i)
{
result *= numberBase;
int c = baseDigits.find(value[i]);
if (c == std::string::npos)
throw std::runtime_error("Invalid character");
result += (unsigned int)c;
}
return result;
}
C'est génial! Merci!