Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
durtan
Feb 21, 2006
Whoooaaaa
I'm working C in Gedit for an edX class and have almost finished this assignment but I keep getting expected expression errors while compiling. Here is the code

code:
#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{
//get money
    double money;

    do
    {
        printf("Give me some money: ");
        money = (double) GetFloat();
    }    
    while (money <= 0.0);
{
    money = round(money*100); 
    int coins;
    
    while (money > 0)
 //check quarters
        {
            if ((int) money%25==0)
                money = money - 25;
                coins++;
 //check dimes
            else if ((int) money%10==0)
                money = money - 10;
                coins++;
 //check nickels
            else if ((int) money%5==0)
                money = money - 5;
                coins++;
 //check pennies
            else if ((int) money%1==0)
                money = money - 1;
                coins++;
             else if (money <= 0)
                break;
         }       
 //return coins
    printf ("%d\n", coins);
}   
    }
And here are the errors.
code:
greedy4.c:27:13: error: expected expression
            else if ((int) money%10==0)
            ^
greedy4.c:31:13: error: expected expression
            else if ((int) money%5==0)
            ^
greedy4.c:35:13: error: expected expression
            else if ((int) money%1==0)
            ^
greedy4.c:38:14: error: expected expression
             else if (money <= 0)
             ^
4 errors generated.
For reference, I'm trying to write a code that counts the fewest amount of coins needed to make the amount inputted. Any advice on why the "expected expression" errors are occurring would be greatly appreciated.

It also is giving me the wrong answer for .41, and is saying 5 coins instead of 4. All the other test answers are going okay except 0.41. Any hints on where I might be going wrong (without anyone blatantly giving me the code) will also be appreciated. This is the code that compiles okay and is mostly correct:
code:
#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{
//get money
    double money;

    do
    {
        printf("Give me some money: ");
        money = (double) GetFloat();
    }    
    while (money <= 0.0);
{
    money = round(money*100); 
    int coins;
    
    for (coins=0; money > 0; coins++)
 //check quarters
        {
            if ((int) money%25==0)
                money = money - 25;
 //check dimes
           else if ((int) money%10==0)
                money = money - 10;
 //check nickels
            else if ((int) money%5==0)
                money = money - 5;
 //check pennies
            else if ((int) money%1==0)
                money = money - 1;
             else if (money <= 0)
                break;
         }       
 //return coins
    printf ("%d\n", coins);
}   
    }

durtan fucked around with this message at 23:37 on Feb 21, 2014

Adbot
ADBOT LOVES YOU

Xerophyte
Mar 17, 2008

This space intentionally left blank
When you write
C++ code:
if ((int) money%25==0)
money = money - 25;
coins++;
else if ( ... )
the compiler has no way to know that you actually meant this if to apply to the next two statements. It'll interpret the if as applying to the next and only the next statement, i.e. as
C++ code:
if ((int) money%25==0) {
  money = money - 25;
}
coins++;
else if ( ... )
The else is unattached to an if, which is the error you're getting. If you want it to apply to two statements, you need to explicitly group them in a block statement
C++ code:
if ((int) money%25==0) {
  money = money - 25;
  coins++;
}
else if ( ... )

nielsm
Jun 1, 2009



First, you should use [code] tags instead of [quote] tags to post program code, it formats much nicer, and shows up when you press the Quote button on the forums.

Second, your problem is that you aren't grouping your statements into blocks. Add some { } around the stuff your individual if-conditions applies to.

durtan
Feb 21, 2006
Whoooaaaa

nielsm posted:

First, you should use [code] tags instead of [quote] tags to post program code, it formats much nicer, and shows up when you press the Quote button on the forums.

Second, your problem is that you aren't grouping your statements into blocks. Add some { } around the stuff your individual if-conditions applies to.

Thanks for the [code] info. I fixed my original post.

And yes, adding {} definitely helped the expected expression issues. Thanks for the advice Xerophyte and nielsm. In regards to getting the wrong output, I'm fairly certain it has something to do with how I'm rounding the float. I will mess around a bit with it.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

You should consider using an integer to store the number of pennies instead of floating point.

durtan
Feb 21, 2006
Whoooaaaa

taqueso posted:

You should consider using an integer to store the number of pennies instead of floating point.

Do you mean the money variable being stored as an integer? Doesn't the underlined part convert the float to an int? Or is it converting it back to a float because I declared the variable a float in the beginning?

quote:

money = (int) round(money*100);

Edit: I apologize if I'm asking stupid questions, this is new stuff to me and I'm trying to research the best I can.

durtan fucked around with this message at 00:13 on Feb 22, 2014

nielsm
Jun 1, 2009



A variable stays the type it was declared as. When you assign something to it, it either gets converted in one way or another (depending on the types involved), or there is no automatic conversion and the assignment is a compile-time error.
The effect of that int cast is really just performing a truncation operation on the number, it gets converted to int and right back to double.

durtan
Feb 21, 2006
Whoooaaaa
So would it make sense to create an int variable from the double variable?

Edit: Doesn't seem to make a difference. Creating an int variable from the float variable gives me the right number but I'm still counting 5 coins instead of 4. Adding a <= 0 check at the beginning of the for loop and getting the coins variable to increment in each else if statement doesn't seem to give me the right answer either.
code:
#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{
//get money
    float money;
    int money1;

    do
    {
        printf("Give me some money: ");
        money = GetFloat();
        money1 = money*100;
    }    
    while (money <= 0);
    
{
    int coins;
    
    for (coins=0; money1 > 0;)
 //check zero
        {
            if (money1<=0)
            {
            break;
 //check quarters
            }
            else if (money1%25==0)
            {
                money1 = money1 - 25;
                coins++;
            }    
 //check dimes
           else if (money1%10==0)
           {
                money1 = money1 - 10;
                coins++;
           }     
 //check nickels
            else if (money1%5==0)
            {
                money1 = money1 - 5;
                coins++;
            }    
 //check pennies
            else if (money1%1==0)
             {
                money1 = money1 - 1;
                coins++;
             }   
         }       
 //return coins
    printf ("%d\n", coins);
}   
    }
Still gives me five coins instead of four when I enter ".41".

durtan fucked around with this message at 00:47 on Feb 22, 2014

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

durtan posted:

So would it make sense to create an int variable from the double variable?

Edit: Doesn't seem to make a difference. Creating an int variable from the float variable gives me the right number but I'm still counting 5 coins instead of 4. Adding a <= 0 check at the beginning of the for loop and getting the coins variable to increment in each else if statement doesn't seem to give me the right answer either.
code:
#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{
//get money
    float money;
    int money1;

    do
    {
        printf("Give me some money: ");
        money = GetFloat();
        money1 = money*100;
    }    
    while (money <= 0);
    
{
    int coins;
    
    for (coins=0; money1 > 0;)
 //check zero
        {
            if (money1<=0)
            {
            break;
 //check quarters
            }
            else if (money1%25==0)
            {
                money1 = money1 - 25;
                coins++;
            }    
 //check dimes
           else if (money1%10==0)
           {
                money1 = money1 - 10;
                coins++;
           }     
 //check nickels
            else if (money1%5==0)
            {
                money1 = money1 - 5;
                coins++;
            }    
 //check pennies
            else if (money1%1==0)
             {
                money1 = money1 - 1;
                coins++;
             }   
         }       
 //return coins
    printf ("%d\n", coins);
}   
    }
Still gives me five coins instead of four when I enter ".41".

I think what he's trying to get at is floats don't necessarily behave exactly as you think they will. Generally, it's considered a best practice to store monetary information in fixed point form because $CASHMONIES * $SOME_VAL / $SOME_VAL may not return the desired result. Machine epsilon, etc.

Qwertycoatl
Dec 31, 2008

durtan posted:

Still gives me five coins instead of four when I enter ".41".

Try making it print what the coins are.

And/or trace through in your head or a debugger what path the code will take with that input.

(It's a problem with your logic, rather than syntax or floating point rounding)

hooah
Feb 6, 2006
WTF?
For my architecture class, I have to write a bunch of C functions that will tell if a given double is negative, zero, denormal, NaN, etc. I got started on it and it was going fine, until I was told we can't use floating point operations, so there goes my whole "shift and/or mask, compare to 0" method for figuring stuff out. Now I'm completely lost. Can anyone point me in the right direction?

Spatial
Nov 15, 2007

Comparing to zero doesn't have to be a floating point op.

hooah
Feb 6, 2006
WTF?

Spatial posted:

Comparing to zero doesn't have to be a floating point op.

Yeah, I misunderstood the professor when he told me that.

delta534
Sep 2, 2011

hooah posted:

For my architecture class, I have to write a bunch of C functions that will tell if a given double is negative, zero, denormal, NaN, etc. I got started on it and it was going fine, until I was told we can't use floating point operations, so there goes my whole "shift and/or mask, compare to 0" method for figuring stuff out. Now I'm completely lost. Can anyone point me in the right direction?

It sounds like your teacher wants you to learn about the IEEE floating point format. Start with this since doubles are specified http://en.wikipedia.org/wiki/Double_precision_floating-point_format and that, roughly,
code:
uint64 getBitsOfDouble(double d){
return *(uint64 *)&d;
}
will allow you to get the bits of the double in a usable form

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
Nb. your compiler may yell at you for doing type punning that way :/

schnarf
Jun 1, 2002
I WIN.

delta534 posted:

code:
uint64 getBitsOfDouble(double d){
return *(uint64 *)&d;
}
will allow you to get the bits of the double in a usable form
Yeah, this is undefined behavior. memcpy() is one safe way to do it, which any good compiler will optimize away:
code:
uint64 getBitsOfDouble(double d) {
  uint64 n;
  static_assert(sizeof(n) == sizeof(d), "");
  memcpy(&n, &d, sizeof(n));
  return n;
}

ExcessBLarg!
Sep 1, 2001

schnarf posted:

memcpy() is one safe way to do it
Unions are kosher for type punning in C99. Aren't they?

MrMoo
Sep 14, 2000

unions or memcpy, the compiler is smart enough to recognise either and make it efficient. The classic union required being:
C code:
union {
  struct sockaddr         sa;
  struct sockaddr_in      s4;
  struct sockaddr_in6     s6;
  struct sockaddr_storage ss;
} addr;
Microsoft constantly notes in its APIs with 64-bit words when casting is erroneous:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx

hooah
Feb 6, 2006
WTF?
I'm working on the is_denormal function, but for some reason the program isn't getting into one of my if blocks. Here's the function:
C code:
int is_denormal(double in){
    union dp_item value;
    value.drep = in;
    printf("original value is %016xll\n", value.irep);
    value.irep = value.irep & 0x7ff0000000000000;
    printf("masked value is %016xll\n", value.irep);
    // The if statement that's never true
    if(value.irep == 0){
        value.drep = in;
        printf("value is reset to %16xll\n", value.irep);
        value.irep = value.irep & 0x000fffffffffffff;
        if(value.irep == 0)
            return 0;
        else
            return 1;
    }
    else
        return 0;
}
In my is_zero function, I do the same test that's always false here, but it returns true or false appropriately. Why is this one behaving differently?

schnarf
Jun 1, 2002
I WIN.

ExcessBLarg! posted:

Unions are kosher for type punning in C99. Aren't they?

From what I can see on this page, C99 says that union-based type punning is well-defined, but the C++ standard doesn't appear to say anything on the matter.

Diametunim
Oct 26, 2010
Anyone here ever written Conway's Game of Life? It's my next project for my Foundations of CS class and I have no drat idea what I'm doing.

shrughes
Oct 11, 2008

(call/cc call/cc)
You mean you don't get programming? You don't get the rules of Game of Life? You can't use arrays and translate a simple algorithm into code? What is the nature of your question?

durtan
Feb 21, 2006
Whoooaaaa
Would anyone know an easy way to round a float to one decimal? I was able to fix the logic in my current algorithm but now it is failing a check for 4.2. My print functions are saying the program is converting 4.20000 to 419 and a test program confirms that 4.2 printed to 50 decimals is 4.1999somethingsomething. Here is the code yet again with my test print functions disabled.

code:
#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{
//get money
    float money;
    int money1;

    do
    {
        printf("Give me some money: ");
        money = GetFloat();
        money1 = money*100;
    }    
    while (money <= 0);
    
    //printf("%d %f\n", money1, money);
{
    int coins;
    
    for (coins=0; money1 > 0;)
 //check zero
        {
            if (money1<=0)
            {
            break;
            }
 //check quarters
            else if (money1 - 25>=0)
            {
                money1 = money1 - 25;
                coins++;
                //printf("q %d\n", money1);
            }    
 //check dimes
           else if (money1%10==0)
           {
                money1 = money1 - 10;
                coins++;
                //printf("d %d\n", money1);
           }     
 //check nickels
            else if (money1%5==0)
            {
                money1 = money1 - 5;
                coins++;
                //printf("n %d\n", money1);
            }    
 //check pennies
            else if (money1%1==0)
             {
                money1 = money1 - 1;
                coins++;
                //printf("p %d\n", money1);
             }   
         }       
 //return coins
    printf ("%d\n", coins);
}   
    }

tractor fanatic
Sep 9, 2005

Pillbug
It's not possible to represent 1/10 exactly in floating point format.

durtan
Feb 21, 2006
Whoooaaaa

tractor fanatic posted:

It's not possible to represent 1/10 exactly in floating point format.

Yup. I was hoping to multiply the 4.1999 by 10 and round it that way before bringing it forward again. I fixed it by rounding the variable by 100 as so:
code:
printf("Give me some money: ");
        money = GetFloat();
        money1 = roundf(money*100);
Which made my code work as intended! Yay!

shrughes
Oct 11, 2008

(call/cc call/cc)
You can just add 0.5 and use integer truncation (if it's positive). It wouldn't work if you're one ulp under 0.5 though. Or between 2^23 and 2^24.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

schnarf posted:

From what I can see on this page, C99 says that union-based type punning is well-defined, but the C++ standard doesn't appear to say anything on the matter.

You should interpret the C committee's notions of type-based alias analysis as aspirational at best.

Seriously, they just can't agree what the actual rule design should be, and it seems like anybody with any mathematical sense fled that committee years ago.

It is all really vague, and clang's rule of "if you make it really obvious that you're breaking the type-punning rules, we promise not to gently caress everything up" is probably the best take on the whole thing that anybody's going get.

Spatial
Nov 15, 2007

Are there any plans to improve the shittier aspects of C++? I mean god drat. It's 2014 and imports are still done by copy-and-pasting files into each other using preprocessor macros. That is some truly shameful poo poo.

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"

Spatial posted:

Are there any plans to improve the shittier aspects of C++? I mean god drat. It's 2014 and imports are still done by copy-and-pasting files into each other using preprocessor macros. That is some truly shameful poo poo.

There's a group working on modules with tentative inclusion in C++1y, so that's three years off at best? Here's Clang's page on their support for it, and here's the latest paper on the proposal AFAIK.

xgalaxy
Jan 27, 2004
i write code
Just learn to love the poo poo pool that is C++ because I doubt it is going to get any better. Honestly people are praising how great C++ 11 has made the language, and I agree in some areas the language is a little better, but it has also made things worse IMO.

I'm really hoping rust or D pick up enough steam so I can move on from this poo poo show for good. Until then I'm just going to try and live with the mess. I don't really like how dense the syntax is with rust, and D I am not fond of the garbage collection stuff. It will be interesting to see how these two things evolve.

xgalaxy fucked around with this message at 17:59 on Feb 23, 2014

Rottbott
Jul 27, 2006
DMC
What has C++11 made worse?

xgalaxy
Jan 27, 2004
i write code

Rottbott posted:

What has C++11 made worse?

I don't like how rvalue references were implemented. Given the restrictions of not breaking compatibility, etc. there isn't much different they could have done. But I dislike how you have to litter your code with std::move and std::forward, not to mention the horror of T&& in already verbose and hard to read templates. In addition its a easy to screw up rvalue references and end up doing needless copying because you forgot to add an std::move in your copy (move) constructor for example.

I think it is a bit of a joke how they introduced this new alternative style function syntax. Maybe instead of introducing a new way of declaring functions you just instead accept the fact that you can't solve certain classes of problems with the C++ template language, eg. returning a T + U type. Maybe I'm just on my own in this line of thought, but C++ is difficult enough already. Is hard enough to read already. Do we really need an additional way of writing functions for this feature? Maybe just accept the limitation on move on.

Explicit overrides and final are great in other languages like C# but they are basically a wet noodle in C++11, again they had backwards compatibility to be concerned about. These two additions are basically useless in C++ 11 because there is nothing 'enforcing' their use. So they are going to have the same problems as virtual had where someone, somewhere, forgets to add them.

xgalaxy fucked around with this message at 20:35 on Feb 23, 2014

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

xgalaxy posted:

Explicit overrides and final are great in other languages like C# but they are basically a wet noodle in C++11, again they had backwards compatibility to be concerned about. These two additions are basically useless in C++ 11 because there is nothing 'enforcing' their use. So they are going to have the same problems as virtual had where someone, somewhere, forgets to add them.
That seems a bit weird - is there really nothing you can turn on to enforce those things? Like -Wall can shout at you about a lot of things, it seems like there should be a -WstrictC++11 or something.

Rottbott
Jul 27, 2006
DMC
I would love an official "strict" mode which turns off a bunch of backwards compatibility stuff.

R-value references seem ok. For most classes, the compiler-generated methods are good enough, so I only find myself actually writing code using them when doing something fancy i.e. rarely. I think of them like templates, they can make libraries nice and simple to use, but aren't much fun to write.

I like override and final even though their use is sadly not enforced. Previously I always wrote 'virtual' on overridden methods even though it does nothing, just to make it obvious when you read the code. Override is a nice replacement for doing that.

That Turkey Story
Mar 30, 2003

xgalaxy posted:

I don't like how rvalue references were implemented. Given the restrictions of not breaking compatibility, etc. there isn't much different they could have done. But I dislike how you have to litter your code with std::move and std::forward, not to mention the horror of T&& in already verbose and hard to read templates. In addition its a easy to screw up rvalue references and end up doing needless copying because you forgot to add an std::move in your copy (move) constructor for example.
I don't disagree that it's complicated to make optimal use of moving and forwarding, especially if you also don't want to prohibit things like RVO, but do you have an alternative syntactical suggestion to make it less verbose and in a way that doesn't risk screwing things up by default?

xgalaxy posted:

I think it is a bit of a joke how they introduced this new alternative style function syntax. Maybe instead of introducing a new way of declaring functions you just instead accept the fact that you can't solve certain classes of problems with the C++ template language, eg. returning a T + U type. Maybe I'm just on my own in this line of thought, but C++ is difficult enough already. Is hard enough to read already. Do we really need an additional way of writing functions for this feature? Maybe just accept the limitation on move on.
It really is something that I feel is important, although in an ideal world, we'd just only have the alternative syntax (I.E. ditch the "regular" function declaration syntax entirely).

xgalaxy posted:

Explicit overrides and final are great in other languages like C# but they are basically a wet noodle in C++11, again they had backwards compatibility to be concerned about. These two additions are basically useless in C++ 11 because there is nothing 'enforcing' their use. So they are going to have the same problems as virtual had where someone, somewhere, forgets to add them.
Yeah I couldn't care less about the override and final stuff.

Diametunim
Oct 26, 2010
This should be a relatively simple question, I'm having trouble compiling a program I'm working on. I'm trying to move away from compiling in Dev C++ because it's a god awful IDE in my opinion and I'm trying to start using Visual Studio. However, visual studio doesn't like lines 43 & 53 (Indicated with arrows), why? This program runs fine in Dev C++ I assume this is a compiler issue?

code:
#ifdef linux 
#define LINUX true
#define WINDOWS false
#endif

#ifdef __WIN32__ 
#define LINUX false 
#define WINDOWS true
#endif


#include <iostream>
#include <fstream>

#include "life.h"

const char FILE_NAME[] = "glider_gun_fight.txt";

using namespace std;

const int NUM_GENERATIONS = 10; //set to a smaller number for debugging

int main() 
{
    populateWorld(FILE_NAME);
        
    showWorld();

    for (int iteration = 0; iteration < NUM_GENERATIONS; iteration++) 
    {
   
        if (WINDOWS) <--------------------------------
           system("cls"); //Windows only
        else
           system("clear"); //Linux only
    
        iterateGeneration();
    
        showWorld();
    } 

    if (WINDOWS) <---------------------------------
        system("PAUSE");
    
    return 0;
}
It should be noted this file was given to me by the professor and we aren't allowed to modify it in any way.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
what the gently caress kind of source code is that

nielsm
Jun 1, 2009



Can you post the exact error message you get from the compiler?

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
I'm guessing that neither linux nor __WIN32__ are defined.

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Yeah, __WIN32__ seems to be a MinGW-ism. Microsoft documents that the define you should use is _WIN32.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply