int safe_multiply(int* error, int x, int y) { int product = 0; int bits_in_int = (sizeof(int) * 8) - 1; *error = 0; if (number_of_bits(x) + number_of_bits(y) <= bits_in_int) { product = x * y; } else { *error = 1; } return product; }
int safe_add(int* error, int x, int y) { int sum = 0; int bits_in_int = (sizeof(int) * 8) - 1; *error = 0; if (number_of_bits(x) < bits_in_int && number_of_bits(y) < bits_in_int) { sum = x + y; } else { *error = 1; } return sum; }
inline T prev_power_of_2(T x) { for (T i = 1; i < number_of_bits(x); i += i) x |= (x >> i); return x - (x >> 1); }
inline T next_power_of_2(T x) { if (x == 0) return 1; x--; for (T i = 1; i < number_of_bits(x); i += i) x |= (x >> i); return ++x; }
static int unpack_long(grib_accessor* a, long* val, size_t *len) { int ret=GRIB_SUCCESS; size_t size=0; size_t i; double max,min,d,b; double *values=0; long binaryScaleFactor,decimalScaleFactor; grib_accessor_second_order_bits_per_value* self = (grib_accessor_second_order_bits_per_value*)a; if (self->bitsPerValue) { *val=self->bitsPerValue; return GRIB_SUCCESS; } if((ret = grib_get_size(a->parent->h, self->values,&size)) != GRIB_SUCCESS) { *val=self->bitsPerValue; return GRIB_SUCCESS; } if((ret = grib_get_long(a->parent->h, self->binaryScaleFactor,&binaryScaleFactor)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h, self->decimalScaleFactor,&decimalScaleFactor)) != GRIB_SUCCESS) return ret; values=grib_context_malloc_clear(a->parent->h->context,sizeof(double)*size); if (!values) { grib_context_log(a->parent->h->context,GRIB_LOG_FATAL,"%s unable to allocate %ld bytes", a->name,(long)size); return GRIB_OUT_OF_MEMORY; } if((ret = grib_get_double_array_internal(a->parent->h, self->values,values,&size)) != GRIB_SUCCESS) return ret; max=values[0]; min=max; for (i=1;i<size;i++) { if (max<values[i]) max=values[i]; if (min>values[i]) min=values[i]; } d=grib_power(-decimalScaleFactor,10); b=grib_power(-binaryScaleFactor,2); /* self->bitsPerValue=(long)ceil(log((double)((max-min)*d+1))/log(2.0))-binaryScaleFactor; */ self->bitsPerValue=number_of_bits((unsigned long)(fabs(max-min)*b*d)); *val=self->bitsPerValue; grib_context_free(a->parent->h->context,values); return ret; }