Controllo overflow

di il
20 risposte

Controllo overflow

Salve ho una domanda all'apparenza banale ma che mi sta creando qualche problema. Sto lavorando su un problema di notazione polacca con controlllo overflow. L'utente deve inserire una stringa da stdin nella forma della notazione ( non è importante il problema quanto l'overflow) e controllare che il programma non crei overflow nella somma fra interi. Allora il mio quesito è questo: se l'utente inserisce i valori in stdin maggiori del massimo intero rappresetabile e io con strtok accedo ai valori, quando con atoi() li converto in interi non viene acquisito il numero perchè troppo grande. Come posso fare per controllarlo.
Inoltre se ho due interi come faccio a controllare se la moltiplicazione non crea overflow?
Grazie anticipatamente per l'aiuto.

20 Risposte

  • Re: Controllo overflow

    Potresti non usare la atoi()
    Calcoli il valore cifra a cifra
    Per ogni cifra confronti il valore calcolato con il massimo intero,
    Dalla differenza calcoli quanto puoi ancora salire
    E poi controlli se la cifra successiva e troppo grande
  • Re: Controllo overflow

    Https://en.m.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library
  • Re: Controllo overflow

    Però così eviti del tutto il problema dello overflow

    Forse invece per l'esercizio serve di "riconoscerlo preventivamente"
  • Re: Controllo overflow

    Anzi ancora più semplice
    Siccome viene espressamente richiesto il controllo di possibili overflow nella somma

    Basta sottrarre il primo operando dal massimo intero rappresentabile
    Se il risultato è inferiore al secondo operando sappiamo che avremmo overflow

    Occorre specificare bene cosa si vuole
  • Re: Controllo overflow

    La funzione per la somma sicura con overflow l'avevo ottenuta proprio con la sottrazione del massimo intero al valore, e poi controllando il valore ottenuto con il secondo valore. Per la moltiplicazione avevo provato a fare una cosa simile, ovvero dividere il massimo possibile per un valore ottenendo il massimo moltiplicatore. Tuttavia mi sembra una strada scorretta...
    Inoltre il problema è che ad esempio se l'utente digita
    234455555556 - 1 *, il programma deve dare overflow perché il primo numero è troppo grande per essere memorizzato su un intero. Come faccio a controllare che sia troppo grande se memorizzadolo lo "" "perdo" "" ?
  • Re: Controllo overflow

    Luuukeeeee ha scritto:


    Inoltre il problema è che ad esempio se l'utente digita
    234455555556 - 1 *, il programma deve dare overflow perché il primo numero è troppo grande per essere memorizzato su un intero. Come faccio a controllare che sia troppo grande se memorizzadolo lo "" "perdo" "" ?
    Invece di confrontare due interi, puoi sempre confrontare due stringhe!

    Inoltre volendo ti puoi anche divertire ad implementare una libreria che provveda alle operazioni aritmetiche tra numeri rappresentati tra stringhe (superando in questo modo il problema overflow). Qualche tempo fa l'ho fatto pure io implementando i classici metodi adoperati con carte e penna.
  • Re: Controllo overflow

    Acquisisci l'intera linea come array di char.
    Tralasciando per un attimo il segno, conti il numero di cifre con un while - nel caso di 234455555556 hai n = 12.
    Se 10^n > INT_MAX sei in overflow.
    In caso di moltiplicazione, se 10^(n1+n2) > INT_MAX sei in overflow

    INT_MAX o se vuoi più bit LONG_MAX o addirittura LLONG_MAX li trovi in limits.h
  • Re: Controllo overflow

    Per sapere se una somma va in overflow c'è un modo che non include stringhe. La somma di due numeri può essere intesa come:
    " ho due mucchi di sassi, ogni volta prendo un sasso da un mucchio e lo posto nel secondo. L'operazione Finisce quando il mucchio da cui prendo i sassi è vuoto e il risultato dell'operazione è il secondo mucchio di sassi."
    Quindi io ho tre variabili: mucchio 1 mucchio 2 e Somma. Il valore dei due mucchi è dato dall' utente. Come prima operazione rendo somma uguale a uno di essi. Successivamente scrivo una for che ogni passo faccia scendere di uno il valore dell'altro mucchio, fino a quando questo non diventa 0. All'interno della for faccio aumentare di 1 la variabile di Somma.

    Così facendo apparentemente non ho ottenuto nulla, Anzi è solo molto più lento fare la somma. Invece il gioco sta Tutto qui, perché per sapere se è avvenuto un overflow mi basterà verificare, In for, se il valore di Somma è minore del valore di Somma meno 1. Così facendo non solo so se è avvenuto ma anche esattamente quando.
  • Re: Controllo overflow

    Weierstrass ha scritto:


    Tralasciando per un attimo il segno, conti il numero di cifre con un while - nel caso di 234455555556 hai n = 12.
    Se 10^n > INT_MAX sei in overflow.
    Ok, ma anche se la suddetta diseguaglianza non è verificata puoi essere in overflow!
  • Re: Controllo overflow

    Nippolo ha scritto:


    Weierstrass ha scritto:


    Tralasciando per un attimo il segno, conti il numero di cifre con un while - nel caso di 234455555556 hai n = 12.
    Se 10^n > INT_MAX sei in overflow.
    Ok, ma anche se la suddetta diseguaglianza non è verificata puoi essere in overflow!
    E come?

    (numero acquisito) < 10^n <= INT_MAX
  • Re: Controllo overflow

    Ripensandoci Esiste un modo ancora più semplice, se si parla di somme ( tra numeri dello stesso segno). Il valore assoluto della somma deve essere sempre maggiore del valore assoluto di entrambi gli addendi.
    Invece se si parla di sottrazioni ( numeri di segno opposto) la somma deve essere compresa tra i due addendi.
    3+2=5 5>3,5>2.
    -3-2=-5 5>3,5>2
    3-2=1 3<1<-2
    -3+2=-1 -3<-1<+2
  • Re: Controllo overflow

    Facendo un resoconto
    Per vedere se un numero dato in una stringa è maggiore del massimo rappresentabile uso strcmp tra il massimo e il token ottenuto dalla stringa?
    Per la moltiplicazione l'algoritmo dell'esponente non so se sia corretto perché ad esempio se il massimo fosse 800 e io facessi la somma tra 800 e 1 otterrei 801 quindi 10^3<800 ma sono comunque in overflow!
  • Re: Controllo overflow

    Ti basta fare le operazioni in parallelo sia sui numeri che sulle stringhe. Una volta che avrei svolto l'operazione in entrambi i modi ti basterà fare una strcmp tra la stringa risultato e la stringa ottenuta dalla itoa del numero risultato. Se le due stringhe sono diverse c'è stato overflow.
  • Re: Controllo overflow

    Weierstrass ha scritto:


    E come?
    ...
    Scusa ho scritto una cosa per un'altra. Intendevo che anche se la suddetta diseguaglianza è verificata, puoi non essere in overflow!
    Esempio:
    12.345(int_16) ==> n=5
    10^n=100.000>int_16_max=32.767
Devi accedere o registrarti per scrivere nel forum
20 risposte