Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jan 25, 2009, 09:53 AM   #1
mdeh
macrumors 6502
 
Join Date: Jan 2009
Kochan 2.0 Exercise 10-6

Here is the exercise in full:

Based on the following definitions

float f = 1.00;
short int i = 100;
long int l = 500L;
double d = 15.00;


and the seven steps outlined in this chapter for the conversion of operands in expressions, determine the type and value of the following expressions:

f + i
l / d
i / l + f
l * i
f / 2
i / (d + f)
l / (i * 2.0)
l + i / (double) l
>>>>>>>>>>>>>>>>>

Here is what I **thought** I would try and do.

someGenericType result;

result = f + i;

if (SomeTestToDetermineResult == float)
NSLOG(@"Result of f + i is a float");



But quickly ran into problems trying to find a "someGenericType". I **think** what the author means is using the "grammatical rules of syntax, what would you expect to find, as opposed to a program that does what I am trying to do, viz use a generic return data type, then test that type and declare what it is.

Any ideas?
mdeh is offline   0 Reply With Quote
Old Jan 25, 2009, 11:39 AM   #2
lee1210
macrumors 68040
 
lee1210's Avatar
 
Join Date: Jan 2005
Location: Dallas, TX
I could not come up with a way to do this in C or Objective-C (take an expression and get its type). The typeof gcc extension would allow you to define a new type with the type of an expression, but that still doesn't help.

Using the sizes you can narrow it down, but it's not an "answer":
Code:
#include <stdio.h>

const char *type_string(int);

int main(int argc, char *argv[]) {
  float f = 1.00;
  short int i = 100;
  long int l = 500L;
  double d = 15.00;

  printf("Size of f + i: %d\n",sizeof(f + i));
  printf("Size of l / d: %d\n",sizeof(l / d));
  printf("Size of i / l + f: %d\n",sizeof(i / l +f));
  printf("Size of l * i: %d\n",sizeof(l * i));
  printf("Size of f / 2: %d\n",sizeof(f / 2));
  printf("Size of i / (d + f): %d\n",sizeof(i / (d + f)));
  printf("Size of l / (i * 2.0): %d\n",sizeof(l / (i * 2.0)));
  printf("Size of l + i / (double) l: %d\n",sizeof(l + i / (double) l));

  printf("Type of f + i: %s\n",type_string(sizeof(f + i)));
  printf("Type of l / d: %s\n",type_string(sizeof(l / d)));
  printf("Type of i / l + f: %s\n",type_string(sizeof(i / l +f)));
  printf("Type of l * i: %s\n",type_string(sizeof(l * i)));
  printf("Type of f / 2: %s\n",type_string(sizeof(f / 2)));
  printf("Type of i / (d + f): %s\n",type_string(sizeof(i / (d + f))));
  printf("Type of l / (i * 2.0): %s\n",type_string(sizeof(l / (i * 2.0))));
  printf("Type of l + i / (double) l: %s\n",type_string(sizeof(l + i / (double) l)));

  return 0;
}

const char *type_string(int in) {
  switch(in) {
    default:
      return "unknown type";
      break;
    case 1:
      return "char";
      break;
    case 2:
      return "short int";
      break;
    case 4:
      return "float or int";
      break;
    case 8:
      return "double or long int";
      break;
    case 12:
    case 16:
      return "long double";
      break;
  }
}
Note that i am only posting code because i don't think you are supposed to write code for this, but follow the implicit casting/promotion rules to solve this. The results of this program are ambiguous enough that it doesn't give it away for you.

Since C++ is more type-safe, and allows for overloading functions, you can do this there... I honestly can't say if the rules are the same in C and C++. There is enough else that is different between the two that i wouldn't bet my life on it, but i am pretty sure they are the same in this case. Anyhow, don't run this code unless you want the answers given away:
Code:
#include <iostream>
#include <string>

std::string myType(char);
std::string myType(short int);
std::string myType(int);
std::string myType(long int);
std::string myType(float);
std::string myType(double);
std::string myType(long double);

int main(int argc, char *argv) {
  float f = 1.00;
  short int i = 100;
  long int l = 500L;
  double d = 15.00;
  std::cout <<"Type of f + i: " << myType(f + i) << std::endl;
  std::cout <<"Type of l / d: "<<myType(l / d) << std::endl;
  std::cout <<"Type of i / l + f: "<<myType(i / l +f) << std::endl;
  std::cout <<"Type of l * i: "<<myType(l * i) << std::endl;
  std::cout <<"Type of f / 2: "<<myType(f / 2) << std::endl;
  std::cout <<"Type of i / (d + f): "<<myType(i / (d + f)) << std::endl;
  std::cout <<"Type of l / (i * 2.0): "<<myType(l / (i * 2.0)) << std::endl;
  std::cout <<"Type of l + i / (double) l: "<<myType(l + i / (double) l) << std::endl;
}

std::string myType(char in) {
  std::string ret = "char";
  return ret;
}

std::string myType(short int in) {
  std::string ret = "short int";
  return ret;
}

std::string myType(int in) {
  std::string ret = "int";
  return ret;
}

std::string myType(long int in) {
  std::string ret = "long int";
  return ret;
}

std::string myType(float in) {
  std::string ret = "float";
  return ret;
}

std::string myType(double in) {
  std::string ret = "double";
  return ret;
}

std::string myType(long double in) {
  std::string ret = "long double";
  return ret;
}
Since you can mix Objective-C and C++, I suppose you could get away with this. The formatting on my couts is a little sloppy, because i was just using s// somewhat haphazardly to turn printfs into couts. Again, I really don't think you are supposed to write code for this.

I tried to think of something goofy to do in C. I was thinking if there would be some way to get the pointer to the result of an expression (no such luck, at least in GCC), it could be cast to void *, then with some memcpy'ing, typecasting, and dependence on different memory representations of the same value as different types of the same width (double vs. long int, int vs. float) except for 0, one might be able to jury rig something. My attempts failed, but that doesn't mean this is impossible.

Your idea doesn't quite work out, because the primitives are not classes, so you can't have a generic primitive. For objects there is the option to do introspection at runtime, but there's no option for that sort of thing here. Since you can't overload methods in Objective-C (if you have the same method name, it must have the same argument types and return type), you can't write a class that emulates the C++ behavior above.

Someone may be more clever than I am and be able to figure out a way to handle this in plain C or Objective-C, but it is definitely impractical, and once more not likely to be what the author was hoping for.

-Lee
lee1210 is offline   0 Reply With Quote
Old Jan 25, 2009, 11:46 AM   #3
mdeh
Thread Starter
macrumors 6502
 
Join Date: Jan 2009
Quote:
Originally Posted by lee1210 View Post
I could not come up with a way to do this in C or Objective-C (take an expression and get its type). The typeof gcc extension would allow you to define a new type with the type of an expression, but that still doesn't help.
......snip....


Someone may be more clever than I am and be able to figure out a way to handle this in plain C or Objective-C, but it is definitely impractical, and once more not likely to be what the author was hoping for.

-Lee
Bravo!!! Great effort...I am impressed.
I think the conclusion you reached is probably correct. With the author's directive that answers only use the material covered to that point, there is no way to do this other than using the grammatical syntax rules provided earlier in the chapter.
But...thanks again for the effort.
mdeh is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Learning Obj C - Kochan or Big Nerd Ranch? afousek iPhone/iPad Programming 4 Apr 26, 2014 01:45 PM

Forum Jump

All times are GMT -5. The time now is 08:18 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC