tonyk_av 40 21 января Опубликовано 21 января (изменено) · Жалоба 16 hours ago, _pv said: 16 hours ago, dimka76 said: почему в калькуляторах таких проблем не возникает ? в bcd считают Или используют как в С++ или Java тип BigInt с динамическим увеличением размера. В Java он вообще встроен. Spoiler #pragma once #include "targetver.h" /** * Big integer class, optimized for decimal integers. * Stores and manipulates integers represented as byte arrays, * where each byte is a decimal digit. If you're looking for * robust, bug-free, efficient code, keep looking. This is a quick * and dirty hack. Some day I'll write a templatized BigInt, where * you will be able to select the base in which to store the * number. When that day comes, most of this code will be thrown * away. * * BUGS: * operator-(int) does not work. * * BigInt doesn't play nice with long long. Either use int * or string. * * INVARIANTS: * - capacity is never smaller than 16 * - capacity is not the smallest it can be because every * modifying member function first grows digits as much as * it might ever need and then does its job. * FIELD TESTING: * - Passed numerous problems on Valladolid, including * 107, 288, 324, 424, 465, 485, 495, 560, 619, 623, etc. * * COMPATIBILITY: * - This class was written for the g++ compiler and uses some * of the g++ extensions (like "long double" and the ">?=" * operator). If you want to compile this under Micro$oft's * "compiler", I don't want to talk to you. * * LAST MODIFIED: October 5, 2005 * * This file is part of my library of algorithms found here: * http://www.palmcommander.com:8081/tools/ * LICENSE: * http://www.palmcommander.com:8081/tools/LICENSE.html * Copyright (c) 2002-2004 * Contact author: * igor at cs.ubc.ca **/ //using namespace std; #ifndef __BIGINTEGER_H__ #define __BIGINTEGER_H__ #include <stdio.h> //#include <string.h> //#include <string> #include <iostream> #include <math.h> #include "targetver.h" #ifdef _WIN32_ #include <sstream> #endif #ifdef __MINIOS7__ /* #ifndef RWSTD_NO_LONG_HEADER_NAME # include <strstream.h> #else # include <strstrea.h> #endif */ #endif #ifndef min #define min(x,y) ((x) < (y) ? (x) : (y)) #endif #ifndef max #define max(x,y) ((x) > (y) ? (x) : (y)) #endif class BigInt { private: char *digits; int size; // number of used bytes (digits) int capacity; // size of digits int sign; // -1, 0 or +1 public: /** Creates a BigInt with initial value n and initial capacity cap **/ BigInt( long n, int cap ); /** Creates a BigInt with initial value n **/ BigInt( long n ); /** Creates a BigInt with initial value floor( d ) **/ //BigInt( long double d ); /** Creates a BigInt with value 0 **/ BigInt(); #ifndef __MINIOS7__ /** Creates a BigInt by reading the value from a string **/ // BigInt( string s ); /** Creates a BigInt by reading the value from a C string **/ // BigInt( const char s[] ); #endif /** Copy constructor **/ BigInt( const BigInt &n ); /** Assignment operators **/ const BigInt &operator=( const BigInt &n ); const BigInt &operator=( long n ); /** Cleans up **/ ~BigInt(); /** Removes any leading zeros and adjusts the sign **/ void normalize(); /** Returns the sign of n: -1, 0 or 1 **/ static int sig( long n ); /** Returns the sign of n: -1, 0 or 1 **/ //static int sig( long double n ); /** Returns the number of decimal digits **/ inline int length() { return size; } /** Arithmetic **/ BigInt operator++(); BigInt operator++( int ); BigInt operator--(); BigInt operator--( int ); BigInt operator-(); BigInt operator+ ( long n ); BigInt operator+ ( BigInt n ); BigInt&operator+=( long n ); BigInt&operator+=( BigInt n ); BigInt operator- ( long n ); BigInt operator- ( BigInt n ); BigInt&operator-=( long n ); BigInt&operator-=( BigInt n ); BigInt operator* ( long n ); BigInt operator* ( BigInt n ); void operator*=( long n ); void operator*=( BigInt n ); BigInt operator/ ( long n ); BigInt operator/ ( BigInt n ); void operator/=( long n ); void operator/=( BigInt n ); long operator% ( long n ); BigInt operator% ( BigInt n ); void operator%=( long n ); void operator%=( BigInt n ); long divide( long n ); // Divides storing quotient in *this and returning the remainder BigInt divide( BigInt n ); // Divides storing quotient in *this and returning the remainder //BigInt operator* ( long double n ); // Multiplies by a double and truncates (always under-estimates!) //void operator*=( long double n ); // Multiplies by a double and truncates (always under-estimates!) /** Bitwise arithmetic **/ BigInt operator<< ( int n ); void operator<<=( int n ); BigInt operator>> ( int n ); // Works differently for negative numbers void operator>>=( int n ); // Works differently for negative numbers /* BigInt operator& ( int n ); BigInt operator& ( BigInt n ); void operator&= ( int n ); void operator&= ( BigInt n ); BigInt operator| ( int n ); BigInt operator| ( BigInt n ); void operator|= ( int n ); void operator|= ( BigInt n ); BigInt operator^ ( int n ); BigInt operator^ ( BigInt n ); void operator^= ( int n ); void operator^= ( BigInt n ); BigInt operator~(); */ /** Concatenation ;-) **/ BigInt operator,( int n ); BigInt operator,( BigInt n ); /** Casting **/ bool operator!(); operator bool(); //operator int(); //XXX: Don't do this!!! It takes precedence over operator+(int,BigInt) //operator string(); /** Comparison **/ bool operator<( BigInt n ); bool operator>( BigInt n ); bool operator==( BigInt n ); bool operator<=( BigInt n ); bool operator>=( BigInt n ); bool operator<( long n ); bool operator>( long n ); bool operator==( long n ); bool operator<=( long n ); bool operator>=( long n ); int compare( BigInt n ); /** Returns the lowest value as an integer (watch out for overflow) **/ long toLong( void ); /** Returns the value as a decimal string **/ //string toString(); char* strImage( void ); /** Outputs decimal value to stdout **/ void print(); /** Outputs the decimal value, with commas **/ // void printWithCommas( ostream &out ); private: /** Expansion **/ void grow(); /** I/O Friends **/ // friend istream &operator>>( istream &in, BigInt &n ); // friend ostream &operator<<( ostream &out, BigInt n ); /** Logarithms **/ /* friend long double log2( BigInt x, long double epsilon ); inline friend long double log( BigInt x, long double epsilon ); inline friend long double log10( BigInt x, long double epsilon ); inline friend long double lg( BigInt x, long double epsilon ); inline friend long double ln( BigInt x, long double epsilon ); */ }; #endif // __BIGINTEGER_H__ Spoiler #include "BigInt.h" BigInt operator+( long m, BigInt &n ) { return n + m; } BigInt operator-( long m, BigInt &n ) { return -n + m; } BigInt operator*( long m, BigInt &n ) { return n * m; } BigInt operator/( long m, BigInt &n ) { return BigInt( m ) / n; } BigInt operator%( long m, BigInt &n ) { return BigInt( m ) % n; } /** Misc **/ inline bool isDigit( int c ) { return( c >= ( int )'0' && c <= ( int )'9' ); } /** Input/Output **/ /* istream &operator>>( istream &in, BigInt &n ) // FIXME: see inside { n.size = 0; n.sign = 1; int sign = 1; int c; while( ( c = in.peek() ) >= 0 && ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ) ) in.get(); if( c < 0 || ( c != ( int )'-' && !isDigit( c ) ) ) { in >> c; // XXX: force in.fail() return in; } if( c == ( int )'-' ) { sign = -1; in.get(); } // FIXME: Extremely inefficient! Use a string. while( ( c = in.peek() ) >= 0 && isDigit( c ) ) { in.get(); n *= 10L; n += ( c - ( int )'0' ); } n.sign = sign; //XXX: assign n.sign directly after fixing the FIXME n.normalize(); return in; } ostream &operator<<( ostream &out, BigInt n ) //FIXME: make more efficient { return out << n.toString(); } */ BigInt::BigInt( long n, int cap ) { cap = max( cap, sizeof( n ) * 8 ); capacity = cap; sign = sig( n ); n *= sign; digits = new char[cap]; memset( digits, 0, cap ); for( size = 0; n; size++ ) { digits[size] = (char)(n % 10); n /= 10; } } BigInt::BigInt( long n ) { capacity = 64; sign = sig( n ); n *= sign; digits = new char[capacity]; memset( digits, 0, capacity ); size = 0; while( n ) { digits[size++] = (char)(n % 10); n /= 10; } } /* BigInt::BigInt( long double d ) { capacity = 32; sign = ( d < 0 ? -1 : d > 0 ? 1 : 0 ); d *= sign; digits = new char[capacity]; memset( digits, 0, capacity ); size = 0; d = floor( d ); while( d > 0 ) { int tmp1 = ( int )( ( d - floor( d / 10 ) * 10 ) + 0.5 ), tmp2 = ( 0 > tmp1 ? 0 : tmp1 ); //digits[size++] = 0 >? ( int )( ( d - floor( d / 10 ) * 10 ) + 0.5 ) <? 9; digits[size++] = ( tmp2 < 9 ? tmp2 : 9 ); d = floor( d / 10 ); } } */ BigInt::BigInt() { capacity = 64; sign = 0; digits = new char[capacity]; memset( digits, 0, capacity ); size = 0; } #ifndef __MINIOS7__ /* BigInt::BigInt( string s ) { capacity = max( ( int )s.size(), 16 ); sign = 0; digits = new char[capacity]; memset( digits, 0, capacity ); istringstream in( s ); in >> ( *this ); } BigInt::BigInt( const char s[] ) { capacity = max( ( int )strlen( s ), 16 ); sign = 0; digits = new char[capacity]; memset( digits, 0, capacity ); istringstream in( s ); in >> ( *this ); } */ #endif BigInt::BigInt( const BigInt &n ) { capacity = n.capacity; sign = n.sign; size = n.size; digits = new char[capacity]; memcpy( digits, n.digits, capacity ); } const BigInt &BigInt::operator=( const BigInt &n ) { if( &n != this ) { if( capacity < n.size ) { capacity = n.capacity; delete [] digits; digits = new char[capacity]; } sign = n.sign; size = n.size; memcpy( digits, n.digits, size ); memset( digits + size, 0, capacity - size ); } return *this; } const BigInt &BigInt::operator=( long n ) { sign = sig( n ); n *= sign; for( size = 0; n; size++ ) { digits[size] = (char)(n % 10); n /= 10; } return *this; } BigInt::~BigInt() { delete [] digits; } void BigInt::normalize() { while( size && !digits[size-1] ) size--; if( !size ) sign = 0; } int BigInt::sig( long n ) { return( n > 0 ? 1 : ( n == 0 ? 0 : -1 ) ); } /* int BigInt::sig( long double n ) { return( n > 0 ? 1 : ( n == 0 ? 0 : -1 ) ); } */ long BigInt::toLong( void ) { int result = 0; for( int i = size - 1; i >= 0; i-- ) { result *= 10; result += digits[i]; if( result < 0 ) return sign * 0x7FFFFFFFL; } return sign * result; } /* string BigInt::toString() { string s = ( sign >= 0 ? "" : "-" ); for( int i = size - 1; i >= 0; i-- ) s += ( digits[i] + '0' ); if( size == 0 ) s += '0'; return s; } */ char* BigInt::strImage( void ) { static char buff[ 512 ]; int i = 0; if( sign < 0 ) buff[ i++ ] = '-'; int j; for( j = size - 1; j >= 0; j-- ) buff[ i++ ] = digits[ j ] + '0'; if( size == 0 ) buff[ i++ ] = '0'; buff[ i ] = 0; return buff; } /* void BigInt::print() //FIXME: make more efficient { cout << toString(); } */ /* void BigInt::printWithCommas( ostream &out ) { if( sign < 0 ) out.put( '-' ); for( int i = size - 1; i >= 0; i-- ) { out.put( (unsigned char)(digits[i] + '0') ); if( !( i % 3 ) && i ) out.put( ',' ); } if( size == 0 ) out.put( '0' ); } */ void BigInt::grow() { char *olddigits = digits; int oldCap = capacity; capacity *= 2; digits = new char[capacity]; memcpy( digits, olddigits, oldCap ); memset( digits + oldCap, 0, oldCap ); delete [] olddigits; } BigInt BigInt::operator++() { operator+=( 1 ); return *this; } BigInt BigInt::operator++( int ) { return operator++(); } BigInt BigInt::operator--() { operator-=( 1 ); return *this; } BigInt BigInt::operator--( int ) { return operator--(); } BigInt BigInt::operator-() { BigInt result( *this ); result.sign *= -1; return result; } BigInt BigInt::operator+( long n ) { BigInt result( *this ); result += n; return result; } BigInt BigInt::operator+( BigInt n ) { BigInt result( *this ); result += n; return result; } BigInt &BigInt::operator+=( long n ) { if( size == capacity ) grow(); int nsign = sig( n ); if( !nsign ) return *this; if( !sign ) sign = nsign; if( sign == nsign ) { n *= nsign; long carry = 0; int i; for( i = 0; n || carry; i++ ) { long dig = n % 10; long newdig = digits[i] + dig + carry; digits[i] = (char)(newdig % 10); carry = newdig / 10; n /= 10; } size = max( i, size ); } else operator-=( -n ); return *this; } BigInt &BigInt::operator+=( BigInt n ) { int maxS = max( size, n.size ) + 1; while( maxS >= capacity ) grow(); //FIXME: this is stupid if( !n.sign ) return *this; if( !sign ) sign = n.sign; if( sign == n.sign ) { int carry = 0; int i; for( i = 0; i < maxS - 1 || carry; i++ ) { int newdig = carry; if( i < size ) newdig += digits[i]; if( i < n.size ) newdig += n.digits[i]; digits[i] = newdig % 10; carry = newdig / 10; } size = max( i, size ); } else { n.sign *= -1; operator-=( n ); n.sign *= -1; } return *this; } BigInt BigInt::operator-( long n ) { BigInt result( *this ); result -= n; return result; } BigInt BigInt::operator-( BigInt n ) { BigInt result( *this ); result -= n; return result; } BigInt &BigInt::operator-=( long n ) { if( size == capacity ) grow(); int nsign = sig( n ); if( !nsign ) return *this; if( !sign ) sign = 1; if( sign == nsign ) { BigInt bin = n; if( sign >= 0 && *this < bin || sign < 0 && *this > bin ) { // Subtracting a bigger number operator=( toLong() - n ); return *this; } n *= nsign; int carry = 0; int i; for( i = 0; n || carry; i++ ) { long dig = n % 10; long newdig = digits[i] - dig + carry; if( newdig < 0 ) newdig += 10, carry = -1; else carry = 0; digits[i] = (char)newdig; n /= 10; } normalize(); } else operator+=( -n ); return *this; } BigInt &BigInt::operator-=( BigInt n ) { int maxS = max( size, n.size ) + 1; while( maxS >= capacity ) grow(); //FIXME: this is stupid if( !n.sign ) return *this; if( !sign ) sign = 1; if( sign == n.sign ) { if( sign >= 0 && *this < n || sign < 0 && *this > n ) { // Subtracting a bigger number BigInt tmp = n; tmp -= *this; *this = tmp; sign = -sign; return *this; } int carry = 0; int i; for( i = 0; i < maxS - 1; i++ ) { int newdig = carry; if( i < size ) newdig += digits[i]; if( i < n.size ) newdig -= n.digits[i]; if( newdig < 0 ) newdig += 10, carry = -1; else carry = 0; digits[i] = newdig; } if( carry ) // Subtracted a bigger number, need to flip sign { if( i ) digits[0] = 10 - digits[0]; size = ( i ? 1 : 0 ); for( int j = 1; j < i; j++ ) { digits[j] = 9 - digits[j]; if( digits[i] ) size = j + 1; } sign *= -1; } normalize(); } else { n.sign *= -1; operator+=( n ); n.sign *= -1; } return *this; } BigInt BigInt::operator*( long n ) { BigInt result( 0, size + sizeof( n ) * 8 ); int nsign = sig( n ); n *= nsign; result.sign = sign * nsign; if( !result.sign ) return result; int i, j; for( i = 0; n; i++ ) { long dig = n % 10; if( dig ) { long carry = 0; for( j = 0; j < size || carry; j++ ) { long newDig = result.digits[i + j] + ( j < size ? dig * digits[j] : 0 ) + carry; result.digits[i + j] = (char)(newDig % 10); carry = newDig / 10; } } n /= 10; } result.size = i + j - 1; return result; } BigInt BigInt::operator*( BigInt n ) { BigInt result( 0, size + n.size ); result.sign = sign * n.sign; if( !result.sign ) return result; int i, j; for( i = 0; i < n.size; i++ ) { if( n.digits[i] ) { int carry = 0; for( j = 0; j < size || carry; j++ ) { int newDig = result.digits[i + j] + ( j < size ? n.digits[i] * digits[j] : 0 ) + carry; result.digits[i + j] = newDig % 10; carry = newDig / 10; } } } result.size = i + j - 1; return result; } void BigInt::operator*=( long n ) { operator=( operator*( n ) ); } void BigInt::operator*=( BigInt n ) { operator=( operator*( n ) ); } BigInt BigInt::operator/( long n ) { if( !n ) n /= n; //XXX: force a crash BigInt result( *this ); result /= n; return result; } BigInt BigInt::operator/( BigInt n ) { if( !n ) n.size /= n.size; //XXX: force a crash BigInt result( *this ); result /= n; return result; } void BigInt::operator/=( long n ) { divide( n ); } void BigInt::operator/=( BigInt n ) { divide( n ); } long BigInt::operator%( long n ) { BigInt tmp( *this ); return tmp.divide( n ); } void BigInt::operator%=( long n ) { operator=( divide( n ) ); } BigInt BigInt::operator%( BigInt n ) { BigInt tmp( *this ); return tmp.divide( n ); } void BigInt::operator%=( BigInt n ) { operator=( divide( n ) ); } long BigInt::divide( long n ) { if( !n ) n /= n; //XXX: force a crash int nsign = sig( n ); n *= nsign; if( !sign ) return 0; sign *= nsign; long tmp = 0; for( int i = size - 1; i >= 0; i-- ) { tmp *= 10; tmp += digits[i]; digits[i] = (char)(tmp / n); tmp -= digits[i] * n; } normalize(); return tmp; } BigInt BigInt::divide( BigInt n ) { if( !n ) n.size /= n.size; //XXX: force a crash if( !sign ) return 0; sign *= n.sign; int oldSign = n.sign; n.sign = 1; BigInt tmp( 0, size ); for( int i = size - 1; i >= 0; i-- ) { tmp *= 10; tmp += digits[i]; digits[i] = 0; while( tmp >= n ) { tmp -= n; digits[i]++; } } normalize(); n.sign = oldSign; return tmp; } // This is only exact to the first 15 or so digits, but it is // never an over-estimate /* BigInt BigInt::operator*( long double n ) { // the number of digits after the decimal point to use const int DIGS_AFTER_DOT = 15; int nsign = sig( n ); n *= nsign; int ndigs = n >= 1 ? ( int )log10( n ) + 1 : 0; BigInt result( 0, size + ndigs ); result.sign = sign * nsign; if( !result.sign ) return result; if( n >= 1 ) for( int i = 0; i < ndigs; i++ ) n /= 10; result.size = 0; char afterDot[DIGS_AFTER_DOT + 1]; memset( afterDot, 0, sizeof( afterDot ) ); // Keep going until the DIGS_AFTER_DOT'th digit after the decimal point for( int i = ndigs - 1; i >= -DIGS_AFTER_DOT; i-- ) { n *= 10; int dig = ( int )floor( n ); n -= dig; if( !dig ) continue; int carry = 0; for( int j = 0; j < size || carry; j++ ) { int newdig = ( i + j < 0 ? afterDot[-( i + j )] : result.digits[i + j] ) + dig * digits[j] + carry; ( i + j < 0 ? afterDot[-( i + j )] : result.digits[i + j] ) = newdig % 10; if( i + j >= 0 && result.digits[i + j] ) { //result.size >?= i + j + 1; result.size = max( result.size, i + j + 1 ); } carry = newdig / 10; } } if( !result.size ) result.sign = 0; return result; } void BigInt::operator*=( long double n ) { operator=( operator*( n ) ); } */ BigInt BigInt::operator<<( int n ) { BigInt result( *this ); result <<= n; return result; } void BigInt::operator<<=( int n ) { if( n < 0 ) operator>>=( -n ); else if( n > 0 ) { BigInt mult( 1, 4 * n ); for( int i = ( 1 << 30 ); i; i >>= 1 ) { mult *= mult; if( n & i ) mult *= 2; } operator*=( mult ); } } BigInt BigInt::operator>>( int n ) { BigInt result( *this ); result >>= n; return result; } void BigInt::operator>>=( int n ) { if( n < 0 ) operator<<=( -n ); else if( n > 0 ) { BigInt mult( 1, 4 * n ); for( int i = ( 1 << 30 ); i; i >>= 1 ) { mult *= mult; if( n & i ) mult *= 2; } operator/=( mult ); } } /* BigInt BigInt::operator&( int n ) { } BigInt BigInt::operator&( BigInt n ) { } void BigInt::operator&=( int n ) { } void BigInt::operator&=( BigInt n ) { } BigInt BigInt::operator|( int n ) { } BigInt BigInt::operator|( BigInt n ) { } void BigInt::operator|=( int n ) { } void BigInt::operator|=( BigInt n ) { } BigInt BigInt::operator^( int n ) { } BigInt BigInt::operator^( BigInt n ) { } void BigInt::operator^=( int n ) { } void BigInt::operator^=( BigInt n ) { } BigInt BigInt::operator~() { } */ BigInt BigInt::operator,( int n ) { BigInt result( 0, size + ( int )sizeof( n ) * 8 ); for( result.size = 0; n; result.size++ ) { result.digits[result.size] = n % 10; n /= 10; } memcpy( result.digits + result.size, digits, size * sizeof( digits[0] ) ); result.size += size; result.sign = 1; result.normalize(); return result; } BigInt BigInt::operator,( BigInt n ) { BigInt result( 0, size + n.size ); memcpy( result.digits, n.digits, n.size * sizeof( n.digits[0] ) ); memcpy( result.digits + n.size, digits, size * sizeof( digits[0] ) ); result.size = size + n.size; result.sign = 1; result.normalize(); return result; } bool BigInt::operator!() { return !size; } BigInt::operator bool() { return( size ? true : false ); } //BigInt::operator int() //{ // return toInt(); //} /* BigInt::operator string() { return toString(); } */ bool BigInt::operator<( BigInt n ) { return( compare( n ) < 0 ); } bool BigInt::operator>( BigInt n ) { return( compare( n ) > 0 ); } bool BigInt::operator==( BigInt n ) { return( compare( n ) == 0 ); } bool BigInt::operator<=( BigInt n ) { return( compare( n ) <= 0 ); } bool BigInt::operator>=( BigInt n ) { return( compare( n ) >= 0 ); } bool BigInt::operator<( long n ) { return( compare( BigInt( n ) ) < 0 ); } bool BigInt::operator>( long n ) { return( compare( BigInt( n ) ) > 0 ); } bool BigInt::operator==( long n ) { return( compare( BigInt( n ) ) == 0 ); } bool BigInt::operator<=( long n ) { return( compare( BigInt( n ) ) <= 0 ); } bool BigInt::operator>=( long n ) { return( compare( BigInt( n ) ) >= 0 ); } int BigInt::compare( BigInt n ) { if( sign < n.sign ) return -1; if( sign > n.sign ) return 1; if( size < n.size ) return -sign; if( size > n.size ) return sign; for( int i = size - 1; i >= 0; i-- ) { if( digits[i] < n.digits[i] ) return -sign; else if( digits[i] > n.digits[i] ) return sign; } return 0; } /* long double log2( BigInt x, long double epsilon = 0.000000000000001 ) { static const long double O = 0.0; if( x.sign <= 0 ) return O / O; // Return NaN long double y = 0.0, z = 1.0, f = 0.0; while( x >= 2 ) { if( x.divide( 2 ) ) f += 1.0; f /= 2.0; y++; } f += 1.0; while( z > epsilon ) { f *= f; z /= 2.0; if( f >= 2.0 ) { y += z; f /= 2.0; } } return y; } inline long double log( BigInt x, long double epsilon = 0.000000000000001 ) { return log2( x, epsilon ) * 0.6931471805599; } inline long double log10( BigInt x, long double epsilon = 0.000000000000001 ) { return log2( x, epsilon ) * 0.301029995664; } inline long double lg( BigInt x, long double epsilon = 0.000000000000001 ) { return log2( x, epsilon ); } inline long double ln( BigInt x, long double epsilon = 0.000000000000001 ) { return log( x, epsilon ); } */ Изменено 21 января пользователем tonyk_av Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 21 января Опубликовано 21 января · Жалоба После макросов min и max деже читать этот ахтунг неохота. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 79 21 января Опубликовано 21 января (изменено) · Жалоба А почему же? 🙂 Вангую, щас начнется "конкурс погромистовъ" по стилю написания программы для подсчета булочек и пирожков. Кстати, как-то видел андроид-эмуляцию какого-то калькулятора, у которого происходил сей загадочный эффект, когда было 2,2 + 2,8 = 4,99999. Реально видел. Правда, я сразу же удалил этот "калькулятор" Изменено 21 января пользователем EdgeAligned Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 64 21 января Опубликовано 21 января · Жалоба 4 hours ago, tonyk_av said: Или используют как в С++ или Java тип BigInt с динамическим увеличением размера. В Java он вообще встроен. Особенно на каких-нибудь убогих 4-х битных калькуляторных МК ворочать более чем 512битными числами для представления от 1e-99 до 1e99 Если так не нравятся .0000000002 и .999999999 потому что двоичная плавающая точка не может точно попасть в некоторые числа выраженные в десятичной системе и представить их, логичнее тогда реализовать десятичную плавающую точку, как по ссылке про калькулятор аж из 1974 года Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 40 21 января Опубликовано 21 января · Жалоба 4 hours ago, _pv said: Особенно на каких-нибудь убогих 4-х битных калькуляторных МК ворочать более чем 512битными числами для представления от 1e-99 до 1e99 Быстродействия вычислителя должно хватать для решения практической задачи, и не важно, какая разрядность вычислителя. Этот класс уже восьмой год считает на 16-битном 80186, работающим на 40МГц, 80-байтные числа в адаптивном ПИД-регуляторе печи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться