diff options
author | tomsmeding <tom.smeding@gmail.com> | 2016-10-08 11:58:01 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2016-10-08 11:58:32 +0200 |
commit | 9064811c32218ee1a4adbdb3431d747836bd9bdf (patch) | |
tree | d746455636b509e1d40b0de6ded5385f663b774d | |
parent | f49e2058ad2c6d7eedded27fa41bd30405db5aaa (diff) |
Bigint parsing: also hex, and add string constructor
-rw-r--r-- | bigint.cpp | 42 | ||||
-rw-r--r-- | bigint.h | 1 |
2 files changed, 37 insertions, 6 deletions
@@ -1,4 +1,5 @@ #include <iomanip> +#include <sstream> #include <stdexcept> #include <cctype> #include <cassert> @@ -15,6 +16,10 @@ Bigint Bigint::two(2); Bigint::Bigint() :sign(1){} +Bigint::Bigint(const string &repr){ + stringstream(repr)>>*this; +} + Bigint::Bigint(slongdigit_t v) :digits(1,abs(v)),sign(v>=0?1:-1){ static_assert(sizeof(longdigit_t)==2*sizeof(digit_t), @@ -573,23 +578,48 @@ istream& operator>>(istream &is,Bigint &b){ while(isspace(is.peek()))is.get(); if(!is)return is; b.digits.resize(0); - b.sign=1; - Bigint ten(10); + if(is.peek()=='-'){ + b.sign=-1; + is.get(); + } else b.sign=1; bool acted=false; + if(is.peek()=='0'){ + is.get(); + if(is.peek()=='x'){ + is.get(); + acted=false; + while(true){ + char c=is.peek(); + if(!isdigit(c)&&(c<'a'||c>'f')&&(c<'A'||c>'F'))break; + acted=true; + is.get(); + if(!is)break; + int n; + if(c<='9')n=c-'0'; + else if(c<='F')n=c-'A'+10; + else n=c-'a'+10; + b<<=4; + b+=n; + } + if(!acted)is.setstate(ios_base::failbit); + b.normalise(); + b.checkconsistent(); + return is; + } else acted=true; + } + Bigint ten(10); while(true){ char c=is.peek(); if(!isdigit(c))break; acted=true; is.get(); - if(!is){ - b.checkconsistent(); - return is; - } + if(!is)break; b*=ten; b+=c-'0'; // cerr<<"b="<<b<<endl; } if(!acted)is.setstate(ios_base::failbit); + b.normalise(); b.checkconsistent(); return is; } @@ -32,6 +32,7 @@ public: Bigint(); Bigint(const Bigint&)=default; Bigint(Bigint&&)=default; + explicit Bigint(const std::string&); explicit Bigint(sdigit_t); explicit Bigint(digit_t); explicit Bigint(slongdigit_t); |