Jump to content

I understand the basics of the concept, such as :

x = (y > 8) ? 5 : 4;

Which would return "x" as 4 if "y" is less than 8, and 5 if it is greater than 8, but when you start to nest them, things begin to get confusing for me.

 

Take this for an example:

 

int qty = 45;

double total, u_p = 8.75;

int main() {
	total = qty * u_p *(1.0 - (qty > 50 ? 0.15 : (qty > 20 ? 0.1 : (qty > 10 ? 0.05 : 0.0))));
	return total;
}

This returns 98, even though it should return 354 according to my calculations.

 

I see this as:      total = 45 * 8.75 *(1.0 - 0.1)

 

Why does the compiler return this as 98?

 

Even using printf with a %f specifier throws back some error.

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to comment
https://linustechtips.com/topic/923941-conditional-ternary-operators-in-c/
Share on other sites

Link to post
Share on other sites


#include<stdio.h>

int qty = 45;

double total, u_p = 8.75;

void main() {
    total = qty * u_p *(1.0 - (qty > 50 ? 0.15 : (qty > 20 ? 0.1 : (qty > 10 ? 0.05 : 0.0))));
    printf("%f", total);
}

 

I ran it and worked just fine, printing 354.375000

Link to post
Share on other sites

40 minutes ago, IgorM said:

 


#include<stdio.h>

int qty = 45;

double total, u_p = 8.75;

void main() {
    total = qty * u_p *(1.0 - (qty > 50 ? 0.15 : (qty > 20 ? 0.1 : (qty > 10 ? 0.05 : 0.0))));
    printf("%f", total);
}

 

 

I ran it and worked just fine, printing 354.375000

Indeed it does. Switched to another compiler and it worked just fine. Another question though, are you familiar with macros that have arguments?

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

One thing to consider when it comes to ternarys: They are syntactic sugar meant to provide clean code in some places. If the ternary is hard to read or make things unclear, than you very likely should not use a ternary and instead break the code into if/else statements and intermediate variables that are properly names to make things more legible.

 

99 times out of 10, "better code" is the code that is less complicated and still meets all requirements. "clever" code is almost always a negative unless it serves an actual purpose towards requirements. In other words, I would prefer this same code be written as:

 

int qty = 45;

double total, u_p = 8.75;

double get_modifier(int qty) {
	double mod = 0.0;
	if (qty > 50) {
		mod =  0.15;
	} else if (qty > 20) {
		mod = 0.1;
	} else if (qty > 10) {
		mod = 0.05;
	}
	return 1.0 - mod;
}

int main() {
	total = qty * u_p *get_modifier(qty);
	return total;
}

 

It's a few more vertical space sure, but it's a lot cleaner and easier to add to in the future. Also, the two version compile to nearly the exact same thing, but with a bit of recursion resolution added into the ternary version (at least in the latest MSVC compiler)

Gaming build:

CPU: i7-7700k (5.0ghz, 1.312v)

GPU(s): Asus Strix 1080ti OC (~2063mhz)

Memory: 32GB (4x8) DDR4 G.Skill TridentZ RGB 3000mhz

Motherboard: Asus Prime z270-AR

PSU: Seasonic Prime Titanium 850W

Cooler: Custom water loop (420mm rad + 360mm rad)

Case: Be quiet! Dark base pro 900 (silver)
Primary storage: Samsung 960 evo m.2 SSD (500gb)

Secondary storage: Samsung 850 evo SSD (250gb)

 

Server build:

OS: Ubuntu server 16.04 LTS (though will probably upgrade to 17.04 for better ryzen support)

CPU: Ryzen R7 1700x

Memory: Ballistix Sport LT 16GB

Motherboard: Asrock B350 m4 pro

PSU: Corsair CX550M

Cooler: Cooler master hyper 212 evo

Storage: 2TB WD Red x1, 128gb OCZ SSD for OS

Case: HAF 932 adv

 

Link to post
Share on other sites

1 hour ago, Noirgheos said:

Indeed it does. Switched to another compiler and it worked just fine. Another question though, are you familiar with macros that have arguments?

not much,  but you do you mean something like this?

 


#include<stdio.h>

int qty = 45;
#define OP(X, Y) X * Y *(1.0 - (X > 50 ? 0.15 : (X > 20 ? 0.1 : (X > 10 ? 0.05 : 0.0))))

double total, u_p = 8.75;

void main() {
    total = OP(qty,u_p);
    printf("%f", total);
}

Link to post
Share on other sites

2 hours ago, reniat said:

One thing to consider when it comes to ternarys: They are syntactic sugar meant to provide clean code in some places. If the ternary is hard to read or make things unclear, than you very likely should not use a ternary and instead break the code into if/else statements and intermediate variables that are properly names to make things more legible.

 

99 times out of 10, "better code" is the code that is less complicated and still meets all requirements. "clever" code is almost always a negative unless it serves an actual purpose towards requirements. In other words, I would prefer this same code be written as:

 


int qty = 45;

double total, u_p = 8.75;

double get_modifier(int qty) {
	double mod = 0.0;
	if (qty > 50) {
		mod =  0.15;
	} else if (qty > 20) {
		mod = 0.1;
	} else if (qty > 10) {
		mod = 0.05;
	}
	return 1.0 - mod;
}

int main() {
	total = qty * u_p *get_modifier(qty);
	return total;
}

 

It's a few more vertical space sure, but it's a lot cleaner and easier to add to in the future. Also, the two version compile to nearly the exact same thing, but with a bit of recursion resolution added into the ternary version (at least in the latest MSVC compiler)

Yeah, I agree. This was mostly meant as a somewhat challenging question posed by my teacher.

 

1 hour ago, IgorM said:

not much,  but you do you mean something like this?

 

 


#include<stdio.h>

int qty = 45;
#define OP(X, Y) X * Y *(1.0 - (X > 50 ? 0.15 : (X > 20 ? 0.1 : (X > 10 ? 0.05 : 0.0))))

double total, u_p = 8.75;

void main() {
    total = OP(qty,u_p);
    printf("%f", total);
}

 

Exactly what I meant!  Thank you.

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×