I wonder if I can return error code as double in the following way in C:
double getValue()
{
double ret = 0;
if (error1)
{
return -1;
}
if (error2)
{
return -2;
}
return ret = ....;
}
int main(void)
{
double val = getValue();
if (-1 == val)
{
printf("getValue: error1\n")
return -1;
}
else if (-2 == val)
{
printf("getValue: error2\n");
return -2;
}
......
return 0;
}
so when the return value is >= 0 then it is correct value which can be used for calculations. When value is less than zero error occurred.
Will I get the floating-point-comparison problem when I compare return value with -1 or -2 ?
Flag values are a bad idea. Flag values that are floating point are doubly so, even if double precision.
If you are using IEEE double precision floating point values, the values -1 and -2 are exactly representable as doubles, and comparison is well defined. No "magic error" will slip in if you merely copy the double around or only read the value. In fact, on a system with conventional 2s complement 32 bit ints, every int can be represented exactly as a IEEE double precision floating point value.
Now, transformations you think wouldn't matter like x /3. * 3. will ruin the identity, so the code is very fragile: fragile both because flag values are fragile, and because floating point equivalence is often fragile in practice.
In C++, there are a myriad of ways to do this that are less fragile.
enum error_code {a,b,c};
boost::variant<double, error_code> getValue();
is a tagged union that can hold either a double or an error_code. There is a std::expected proposal you can look at which is a tagged union with a "bias" towards the first value being the only valid one (sort of a cross between std::experimental::optional and boost::variant).
Both of these result in the value being returned in a type-safe way, where an error is a different type of value than the non-error return type.
Alternative solutions include returning the error code separately (as the return value, or taking a pointer-to-error-code as a parameter (what I call ICU style)). The double could be set to some innocuous value in that case (say, NaN) rather than left uninitialized.
double getValue( error_code* e );
or
error_code getValue( double* out );
where enum error_code { a = -1, b = -2 } is an enumeration of the error codes.
#LightnessRacesinOrbit beat me to it, but having typed it I post it anyway.
You can do it by taking the value to be set as a pointer argument, and returning a status. That way, no values of *ret are barred.
int getValue(double *ret)
{
*ret = ...;
if (error1)
return -1;
if (error2)
return -2;
return 0;
}
Then the calling code can be such as
double myval;
int err;
if ((err = getValue(&myval)) == 0)
printf ("getValue() returned %f\n", myval);
else
printf ("getValue() returned error %d\n", err);
Yes, you could get floating-point errors.
So consider using exceptions instead, or perhaps return an int error code and populate a double "out parameter" on success:
int getValue(double& ret)
{
if (error1)
return -1;
if (error2)
return -2;
ret = ....;
return 0;
}
Doing that is not necessary and makes error handling difficult, you should create an enum where you can add or remove error codes as needed, and also you don't really need to remeber what -1 is or what does -2 mean, just give each error a descriptive name, and do this
enum ErrorCodes {NoError, Error1, Error2, ... , ErrorN};
enum ErrorCodes getValue(double *value)
{
if (error1)
return Error1;
if (error2)
return Error2;
.
.
.
if (errorN)
return ErrorN;
*value = resultOfCalculation;
return NoError;
}
then
enum ErrorCode code;
double value;
code = getValue(&value);
switch (code)
{
case NoError:
/* use value here */
break;
case Error1:
/* handle error 1 */
break;
/* and so on */
}
I think this is a lot better and elegant, because you can apply it anytime you want to have robust error checking, no matter what type the target value is, this would work exactly the same for a struct or a double or an int array.
Related
It is a piece of code that gives me error:
const char* name = pAttr->Name(); // attribute name
const char* value = pAttr->Value(); // attribute value
switch(name) // here is where error happens: must have integral or enum type
{
case 'SRAD': // distance from focal point to iso center
double D = atof(value);
break;
case 'DRAD': // distance from iso center to detector
break;
default:
break;
}
The switch(name) is where error happens. It says it must be a integral or enum type. So how do I do switch case, or equivalent, on a char* type?
You cannot use switch here; as the error says, const char* is not supported. It's a good thing, too, because comparing two C-strings through pointers only compares the pointers, not the strings they point to (consider "hello" == "world").
Even if it were, you're trying to compare your C-string to multicharacter literals, which is certainly not what you intended, not least of all because they have type int and an implementation-defined value; I guess you meant to write "SRAD", not 'SRAD'.
Since you're using C++, you should do this:
const std::string name = pAttr->Name();
const std::string value = pAttr->Value();
if (name == "SRAD") {
double D = atof(value.c_str()); // use std::stod(value) in C++11
// ...
}
else if (name == "DRAD") {
// ...
}
else {
// ...
}
(I also fixed your use of name in the initialisation of D; Remy's right — you must have meant value here since "SRAD" cannot possibly be interpreted as a double.)
Another option is to use a local map to store integral values corresponding to the string values, get the integral value from the string, then, use switch on the integral value.
enum { SRAD = 1, DRAD, ... };
static std::map<std::string, int> localMap;
// Fill up the map.
if ( localMap.empty() )
{
localMap["SRAD"] = SRAD;
localMap["DRAD"] = DRAD;
}
const char* name = pAttr->Name(); // attribute name
const char* value = pAttr->Value(); // attribute value
int val = localMap[name];
switch (val)
{
case SRAD: // distance from focal point to iso center
{
double D = atof(value);
break;
}
case DRAD: // distance from iso center to detector
break;
default: // name is unknown
break;
}
Ok, this is totally, completely EVIL, but I have done it, and it does work:
// Must be a #define because an inline func won't give you a constant
#define MAKECODE(p) ((((p)[0])*0x01000000) \
+ (((p)[1])*0x00010000) \
+ (((p)[2])*0x00000100) \
+ ((p)[3]) )
// Note: I did not verify that the parenthesis matched.
switch(MAKECODE(name))
{
case MAKECODE("SRAD"): // distance from focal point to iso center
double D = atof(name);
break;
case MAKECODE("DRAD"): // distance from iso center to detector
break;
default:
break;
}
NOTE: BAD things will happen if the string name points to is less than 4 characters. Different bad things will happen is the string in the case statements are less than 4 characters (but probably just a compiler error).
this answer posted mostly for fun, but it will work if your name string is guaranteed to always be 4 bytes long.
#include <iostream>
using namespace std;
// precondition: name is exactly 4 chars in length
uint32_t convert(const char* name)
{
uint32_t val = uint32_t(name[3])
+ (uint32_t(name[2]) << 8)
+ (uint32_t(name[1]) << 16)
+ (uint32_t(name[0]) << 24);
return val;
}
int main()
{
const char* name = "SRAD"; // attribute name
const char* value = "10"; // attribute value
switch(convert(name)) // convert the string value to integral type uint32_t
{
case 'SRAD': // use arcane knowledge of C to construct an int32 representation of ascii digits
{
double D = atof(value);
cout << "SRAD " << D << endl;
break;
}
case 'DRAD': // distance from iso center to detector
cout << "some operation on value here " << endl;
break;
default:
break;
}
return 0;
}
A switch statement can only evaluate an expression of an integral or enumeration type (or convertible to such a type), and the expression in each case label must be a constant expression.
'SRAD' is not a string literal. It's a character literal with an implementation-defined value of type int. (This is a nearly useless language feature that I've seen used by mistake more than I've seen it used correctly.)
If you want to use C-style language features, avoiding things like C++'s std::string, the equivalent would be an if/else chain:
if (strcmp(name, "SRAD") == 0) {
// ...
}
else if (strcmp(name, "DRAD") == 0) {
// ...
}
else {
// ...
}
If you use std::string (which is advisable), the code would be similar, except that you can use == rather than strcmp.
You could set up a data structure that lets compute a discrete value that you can then use in a switch/case statement, as R Sahu's answer suggests. This would save the overhead of potentially doing N string comparisons. In my opinion, that would be overkill for a simple case like this. If your actual code is larger and more complex, it's worth considering.
Or you might consider redesigning your data structure so that you store and test an enumeration value directly, and then get a string value from that enumeration value via a lookup table.
Pretty simple problem here:
When I test the wrong data input I give an error message but -1.#IND comes up after it?
for instance I type a negative where there should be a positive and I get "wrong input dummy-1.#IND"
#include "Header.h"
void error_rep(){
cout<<"Wrong input dummy";
}
double ctok(double c){
double j = c *273.15;
if (j >= -273.15){
return j;
}
else
error_rep();
}
int main(){
double c = 0;
cin >> c;
double k = ctok(c);
cout<<k<<endl;
keep_window_open();
}
What does this mean? and why is it coming up? How do I get rid of it?
What does this mean?
It's Microsoftese for "not a number". It means that k is not a valid floating-point number.
and why is it coming up?
When your range test fails, you don't return a value. This gives undefined behaviour; in practice, it's likely to be equivalent to returning an uninitalised value, which is likely to be garbage. Your compiler should warn you about this, if you have suitable warnings enabled.
How do i get rid of it?
I'd report the error by throwing an exception; then nothing can attempt to use the invalid return value if the function fails. Alternatively, you could return a type with a testable "invalid" state, such as boost::optional<double> or std::pair<double, bool>, and test it before use.
By the way, if that's supposed to be converting degrees Celsius to Kelvin, then you want to add 273.15, not multiply by it; and compare with zero after the conversion (or with 273.15 before converting, if you prefer).
A good compiler with all warning turns on, will have say that an execution path doesn't have a return ...,
double ctok(double c){
double j = c *273.15;
if (j >= -273.15){
return j;
}
else {
error_rep();
///here
throw ;//somthing
}
}
and try-catch exception around ctok call
-1.#IND means that the double value is "negative indefinate NaN". Basically the value stored can't be represented as a number in a double.
See http://blogs.msdn.com/b/oldnewthing/archive/2013/02/21/10395734.aspx
As I read, in signed arithmetic there are many cases of undefined behaviour. Thus, I prefer to calculate results (even signed ones) using unsigned arithmetic, which is specified without undefined cases.
However, when the result is obtained using unsigned arithmetic, the last step, the conversion to the signed value remains to be done.
Here is a code I wrote and my question is if the code works in accordance with the rules, i.e., whether it is safe, not relying on some undefined/unspecified behaviour?
/*
function to safely convert given unsigned value
to signed result having the required sign
sign == 1 means the result shall be negative,
sign == 0 means the result shall be nonnegative
returns 1 on success, 0 on failure
*/
int safe_convert(unsigned value, int sign, int *result) {
if (sign) {
if (value > -(unsigned)INT_MIN) return 0; // value too big
if (!value) return 0; // cannot convert zero to negative int
*result = INT_MIN + (int)((-(unsigned)INT_MIN) - value);
} else {
if (value > (unsigned)INT_MAX) return 0; //value too big
*result = (int)value;
}
return 1;
}
Eventually, is there a way that is simpler, not relying on undefined/unspecified behaviour and doing the same thing?
Eventually, is there a way that is simpler, not relying on undefined behaviour and doing the same thing?
short x = (short) value;
int y = (int) value;
But be sure on what integral type you are casting to. value may go out of the range of the signed type used.
The only value that could be problematic is INT_MIN. Therefore I would just do something like
int safe_convert(unsigned value, int sign, int *result) {
if (sign) {
if (value > -(unsigned)INT_MIN) return 0; // value too big
if (-(unsigned)INT_MIN > (unsigned)INT_MAX // compile constant
&&
value == -(unsigned)INT_MIN) // special case
*result = INT_MIN;
else *result = -(int)value;
} else {
if (value > (unsigned)INT_MAX) return 0; //value too big
*result = (int)value;
}
return 1;
}
I don't think that the case of asking for a negative zero justifies an error return.
Conversion from unsigned to signed is not undefined, but implementation defined. From C++ Standard, chapter 4.7 Integral conversions, paragraph 3:
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and
bit-field width); otherwise, the value is implementation-defined
Therefore the following is implementation defined and on many platforms exactly what you may expect (wrap around):
unsigned u = -1;
int i = (int)u;
The condition when sign is false (a positive number) is all ready well handled, it is when sign is true (a negative number) is tricky. So rather than:
if (value > -(unsigned)INT_MIN) return 0; // value too big
*result = INT_MIN + (int)((-(unsigned)INT_MIN) - value);
suggest
// 1st half is for 2's compliment machines
// 2nd half is for symmetric ints like 1's compliment and signed ints
// Optimization will simplify the real code to 1 compare
if ((((INT_MIN + 1) == -INT_MAX) && (value > ((unsigned)INT_MAX + 1u))) ||
(( INT_MIN == -INT_MAX) && (value > (unsigned)INT_MAX ))) return 0;
int i = (int) value;
*result = -i;
The INT_MIN == -INT_MAX tests could be used to conditionally allow a signed zero.
I am a beginner to c++ programming and I am given a task of implementation of fixed point math arithmetic in c++. here I am trying to implementation a function isnan() which returns true if the number is not-a-number else will return false.
Test file
#include "fixed_point_header.h"
int main()
{
fp::fixed_point<long long int, 63> a=fp::fixed_point<long long int, 63>::positive_infinity(); // will assign positive infinity value to a from an function from header
fp::fixed_point<long long int, 63> b=fp::fixed_point<long long int, 63>::negative_infinity(); // will assign positive infinity value to b from an function from header
float nan=fp::fixed_point<long long int, 63>::isnan(a,b);
printf( "fixed point nan value == %f\n", float (nan));
}
In the header I want to do somewhat like the code shown below if positive and negative infinity values are added, the isnan function should return 1 else 0.
Header file
#include fixed_point_header
static fp::fixed_point<FP, I, F> isnan (fp::fixed_point<FP, I, F> x,fp::fixed_point<FP, I, F> y){
/*if ( x + y ) happens, ie. x and y are infinities
{
should return 1; }
else {
should return 0; }
} */
can anyone please tell how to proceed with it? or how to solve this paradigm
I am trying to implementation a function isnan() which returns true if the number is not-a-number else will return false.
That's simple enough; define a reserved value to represent nan (as you have for the infinities), and compare with that:
bool isnan(fixed_point x) {
return x == fixed_point::nan();
}
I want to do somewhat like the code shown below if positive and negative infinity values are added, the isnan function should return 1 else 0
It would be the responsibility of the addition operator to check the inputs and return nan if appropriate:
fixed_point operator+(fixed_point x, fixed_point y) {
if (x == fixed_point::nan() || y == fixed_point::nan()) {
return nan;
}
if (x == fixed_point::positive_infinity()) {
return y == fixed_point::negative_infinity() ? fixed_point::nan() : x;
}
// and so on
}
then the test in main becomes:
bool nan = fixed_point::isnan(a+b);
I'm about to do this in C++ but I have had to do it in several languages, it's a fairly common and simple problem, and this is the last time. I've had enough of coding it as I do, I'm sure there must be a better method, so I'm posting here before I write out the same long winded method in yet another language;
Consider the (lilies!) following code;
// I want the difference between these two values as a positive integer
int x = 7
int y = 3
int diff;
// This means you have to find the largest number first
// before making the subtract, to keep the answer positive
if (x>y) {
diff = (x-y);
} else if (y>x) {
diff = (y-x);
} else if (x==y) {
diff = 0;
}
This may sound petty but that seems like a lot to me, just to get the difference between two numbers. Is this in fact a completely reasonable way of doing things and I'm being unnecessarily pedantic, or is my spidey sense tingling with good reason?
Just get the absolute value of the difference:
#include <cstdlib>
int diff = std::abs(x-y);
Using the std::abs() function is one clear way to do this, as others here have suggested.
But perhaps you are interested in succinctly writing this function without library calls.
In that case
diff = x > y ? x - y : y - x;
is a short way.
In your comments, you suggested that you are interested in speed. In that case, you may be interested in ways of performing this operation that do not require branching. This link describes some.
#include <cstdlib>
int main()
{
int x = 7;
int y = 3;
int diff = std::abs(x-y);
}
All the existing answers will overflow on extreme inputs, giving undefined behaviour. #craq pointed this out in a comment.
If you know that your values will fall within a narrow range, it may be fine to do as the other answers suggest, but to handle extreme inputs (i.e. to robustly handle any possible input values), you cannot simply subtract the values then apply the std::abs function. As craq rightly pointed out, the subtraction may overflow, causing undefined behaviour (consider INT_MIN - 1), and the std::abs call may also cause undefined behaviour (consider std::abs(INT_MIN)). It's no better to determine the min and max of the pair and to then perform the subtraction.
More generally, a signed int is unable to represent the maximum difference between two signed int values. The unsigned int type should be used for the output value.
I see 3 solutions. I've used the explicitly-sized integer types from stdint.h here, to close the door on uncertainties like whether long and int are the same size and range.
Solution 1. The low-level way.
// I'm unsure if it matters whether our target platform uses 2's complement,
// due to the way signed-to-unsigned conversions are defined in C and C++:
// > the value is converted by repeatedly adding or subtracting
// > one more than the maximum value that can be represented
// > in the new type until the value is in the range of the new type
uint32_t difference_int32(int32_t i, int32_t j) {
static_assert(
(-(int64_t)INT32_MIN) == (int64_t)INT32_MAX + 1,
"Unexpected numerical limits. This code assumes two's complement."
);
// Map the signed values across to the number-line of uint32_t.
// Preserves the greater-than relation, such that an input of INT32_MIN
// is mapped to 0, and an input of 0 is mapped to near the middle
// of the uint32_t number-line.
// Leverages the wrap-around behaviour of unsigned integer types.
// It would be more intuitive to set the offset to (uint32_t)(-1 * INT32_MIN)
// but that multiplication overflows the signed integer type,
// causing undefined behaviour. We get the right effect subtracting from zero.
const uint32_t offset = (uint32_t)0 - (uint32_t)(INT32_MIN);
const uint32_t i_u = (uint32_t)i + offset;
const uint32_t j_u = (uint32_t)j + offset;
const uint32_t ret = (i_u > j_u) ? (i_u - j_u) : (j_u - i_u);
return ret;
}
I tried a variation on this using bit-twiddling cleverness taken from https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax but modern code-generators seem to generate worse code with this variation. (I've removed the static_assert and the comments.)
uint32_t difference_int32(int32_t i, int32_t j) {
const uint32_t offset = (uint32_t)0 - (uint32_t)(INT32_MIN);
const uint32_t i_u = (uint32_t)i + offset;
const uint32_t j_u = (uint32_t)j + offset;
// Surprisingly it helps code-gen in MSVC 2019 to manually factor-out
// the common subexpression. (Even with optimisation /O2)
const uint32_t t = (i_u ^ j_u) & -(i_u < j_u);
const uint32_t min = j_u ^ t; // min(i_u, j_u)
const uint32_t max = i_u ^ t; // max(i_u, j_u)
const uint32_t ret = max - min;
return ret;
}
Solution 2. The easy way. Avoid overflow by doing the work using a wider signed integer type. This approach can't be used if the input signed integer type is the largest signed integer type available.
uint32_t difference_int32(int32_t i, int32_t j) {
return (uint32_t)std::abs((int64_t)i - (int64_t)j);
}
Solution 3. The laborious way. Use flow-control to work through the different cases. Likely to be less efficient.
uint32_t difference_int32(int32_t i, int32_t j)
{ // This static assert should pass even on 1's complement.
// It's just about impossible that int32_t could ever be capable of representing
// *more* values than can uint32_t.
// Recall that in 2's complement it's the same number, but in 1's complement,
// uint32_t can represent one more value than can int32_t.
static_assert( // Must use int64_t to subtract negative number from INT32_MAX
((int64_t)INT32_MAX - (int64_t)INT32_MIN) <= (int64_t)UINT32_MAX,
"Unexpected numerical limits. Unable to represent greatest possible difference."
);
uint32_t ret;
if (i == j) {
ret = 0;
} else {
if (j > i) { // Swap them so that i > j
const int32_t i_orig = i;
i = j;
j = i_orig;
} // We may now safely assume i > j
uint32_t magnitude_of_greater; // The magnitude, i.e. abs()
bool greater_is_negative; // Zero is of course non-negative
uint32_t magnitude_of_lesser;
bool lesser_is_negative;
if (i >= 0) {
magnitude_of_greater = i;
greater_is_negative = false;
} else { // Here we know 'lesser' is also negative, but we'll keep it simple
// magnitude_of_greater = -i; // DANGEROUS, overflows if i == INT32_MIN.
magnitude_of_greater = (uint32_t)0 - (uint32_t)i;
greater_is_negative = true;
}
if (j >= 0) {
magnitude_of_lesser = j;
lesser_is_negative = false;
} else {
// magnitude_of_lesser = -j; // DANGEROUS, overflows if i == INT32_MIN.
magnitude_of_lesser = (uint32_t)0 - (uint32_t)j;
lesser_is_negative = true;
}
// Finally compute the difference between lesser and greater
if (!greater_is_negative && !lesser_is_negative) {
ret = magnitude_of_greater - magnitude_of_lesser;
} else if (greater_is_negative && lesser_is_negative) {
ret = magnitude_of_lesser - magnitude_of_greater;
} else { // One negative, one non-negative. Difference is sum of the magnitudes.
// This will never overflow.
ret = magnitude_of_lesser + magnitude_of_greater;
}
}
return ret;
}
Well it depends on what you mean by shortest. The fastet runtime, the fastest compilation, the least amount of lines, the least amount of memory. I'll assume you mean runtime.
#include <algorithm> // std::max/min
int diff = std::max(x,y)-std::min(x,y);
This does two comparisons and one operation (this one is unavoidable but could be optimized through certain bitwise operations with specific cases, compiler might actually do this for you though). Also if the compiler is smart enough it could do only one comparison and save the result for the other comparison. E.g if X>Y then you know from the first comparison that Y < X but I'm not sure if compilers take advantage of this.