GNU/Linux >> Znalost Linux >  >> Linux

Zabránění přetečení celého čísla C

V C je požadovaný soubor záhlaví <stdint.h> a konstanta je UINT32_MAX

static void update_value(char op)
{
    if (op == '+')
        if ( value < (UINT32_MAX - 1))
            value++;    // uint32_t global value
        else
            printf("too big!\n");
    else
       if (value > 0)
           value--;
       else
           printf("too small!\n");
}

Pro C++ můžete použít libovolný počet řešení, která najdete zde:Jaký je C++ ekvivalent UINT32_MAX?


Zjistil jsem, že nejobecnějším řešením je zkontrolovat, zda je inkrementovaná hodnota ve skutečnosti větší než předchozí hodnota, nebo zda je dekrementovaná hodnota menší než předchozí hodnota. Toto funguje pouze v případě, že hodnota není podepsána , nezávisle na velikosti proměnné, a je téměř stejně přenosný jako kód C.

static void update_value(char op)
{
  if (op == '+') {
    if (value + 1 > value) value ++;
  } else {
    if (value - 1 < value) value --;
  }
}

Upozorňujeme, že kód může náhodou fungovat s hodnotami se znaménkem , ale podle standardu C by to bylo nedefinované chování a kompilátory mohou volně nahradit if (value + 1 > value) ... s if (1) ... . Neměli byste ne použijte tento kód s podepsanými hodnotami, pokud nemáte zaveden proces auditování generovaného kódu objektu po jeho propojení .

S gcc a clang budete muset přidat -fwrapv možnost nechat tento kód pracovat pro podepsané hodnoty; s jinými kompilátory se může počet najetých kilometrů lišit.

Rozumným způsobem, jak toho dosáhnout, je být typově specifický a používat konstanty z limits.h . Například:

#include "limits.h"

static void update_int(char op, int *value)
{
  int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != INT_MAX) *value = val + 1;
  } else {
    if (val != INT_MIN) *value = val - 1;
  }
}

static void update_int(char op, unsigned int *value)
{
  unsigned int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != UINT_MAX) *value = val + 1;
  } else {
    if (val != UINT_MIN) *value = val - 1;
  }
}

Možná hledáte <limits> :http://www.cplusplus.com/reference/limits/numeric_limits/

Můžete udělat něco takového, abyste získali to, co chcete:

unsigned int n = numeric_limits<unsigned int>::max()

Máte také tento <cstdint> :http://www.cplusplus.com/reference/cstdint/

UINTN_MAX:Maximální hodnota typu bez znaménka s přesnou šířkou (přesně 2^N-1)


Linux
  1. Použít Ts bez ztráty výstupní hodnoty?

  2. Seřadit podle hexadecimální hodnoty?

  3. Jak funguje „chmod -R 755“.

  1. Zaokrouhlete dělené číslo v bash

  2. Procentuální hodnota s GNU Diff

  3. Maximální PID v Linuxu

  1. Návratová hodnota x =os.system(..)

  2. Jak přidám uživatele do jiné skupiny uživatelů?

  3. Jak se počítá priorita procesu?