From 9064811c32218ee1a4adbdb3431d747836bd9bdf Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 8 Oct 2016 11:58:01 +0200 Subject: Bigint parsing: also hex, and add string constructor --- bigint.cpp | 42 ++++++++++++++++++++++++++++++++++++------ bigint.h | 1 + 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/bigint.cpp b/bigint.cpp index 98846e0..72a882b 100644 --- a/bigint.cpp +++ b/bigint.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -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="<