Thread: converting data types

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    4

    converting data types

    Is it possible for a float type variable to be placed in an area of memory set up as double when using the scanf() function?

    My line of thinking was that a float is 4 bytes and a double is 8 bytes, so this conversion should be ok, it’s like 1/2 a litre into 1 litre right?

    I am confused over a question posed to me that states that this conversion is not possible; maybe I do not understand the question properly. The question is:

    "When utilising the scanf() function, why is it not possible for a float type variable to be placed in an area of memory set up as double?"

    Thanks,

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Use "%f" and a pointer to a float to scan a float
    Use "%Lf" and a pointer to a double to scan a double.
    So long as the conversion and the pointer agree, there shouldn't be a problem

  3. #3
    Quote Originally Posted by Salem
    Use "%f" and a pointer to a float to scan a float
    Use "%Lf" and a pointer to a double to scan a double.
    You meant "%lf"
    Emmanuel Delahaye

    "C is a sharp tool"

  4. #4
    Handy Andy andyhunter's Avatar
    Join Date
    Dec 2004
    Posts
    540
    I am sure it has something to do with how scanf itself functions and nothing to do with whether or not the data types can actually be converted. Maybe somebody who has the C standard laying around would care to enlighten us all.

    BTW Salem I believe he is asking something like this:

    Code:
    double mydouble;
    
    scanf("%f", &mydouble);
    [edit]

    Now I am not up to speed on binary representation of floating point numbers but I would have to guess that scanf does not perform implicit conversions if the type specifier and the variable pointer are of 2 different types. Thus even though a float can be promoted to a double scanf simply dumps the float (real*4) into the high order bits of the double pointer(real*8), thus you will always wind up with a really large negative number.

    Again I could be wrong here as I do not know the interworkings of scanf so do not take this as absolute truth. Just a theory because I cannot seem to find any exact description at this time.

    [/edit]
    Last edited by andyhunter; 01-02-2005 at 12:18 PM.
    i don't think most standard compilers support programmers with more than 4 red boxes - Misplaced

    It is my sacred duity to stand in the path of the flood of ignorance and blatant stupidity... - quzah

    Such pointless tricks ceased to be interesting or useful when we came down from the trees and started using higher level languages. - Salem

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Maybe somebody who has the C standard laying around would care to enlighten us all.
    It's a type mismatch, what more can be said? Because scanf is a variadic function, it can't police what types you give it and has to assume that you did what you said you would do in the format string.
    My best code is written with the delete key.

  6. #6
    Quote Originally Posted by andyhunter
    Code:
    double mydouble;
    
    scanf("%f", &mydouble);
    According to the standard, this clearly invokes an undefined behaviour.

    Should be
    Code:
    float mydouble;
    
    scanf("%f", &mydouble);
    or
    Code:
    double mydouble;
    
    scanf("%lf", &mydouble);
    Emmanuel Delahaye

    "C is a sharp tool"

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I would have to guess that scanf does not perform implicit conversions if the type specifier and the variable pointer are of 2 different types.

    correct, scanf() has no way of knowing what type of data is being passed to it (nor any other variable-argument processing function for that matter) - it relies solely on the format string to obtain that information.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Handy Andy andyhunter's Avatar
    Join Date
    Dec 2004
    Posts
    540
    Alright, now why don't we take this thread a little of topic adn perhaps make a decent reference thread.

    I know there are people who are currently attempting to code an OS / make a server / are comfortable with assembly language around here. Additionally I know that there are quite a few comp sci majors around here. So I pose this question, could somebody explain the binary represenation of floating point numbers and exactly why the above example results in 'undefined behavior'.

    PS - just pretend I am a 3 year old when explaining.

    And if nobody wants to do that maybe at least some good references could be provided.
    i don't think most standard compilers support programmers with more than 4 red boxes - Misplaced

    It is my sacred duity to stand in the path of the flood of ignorance and blatant stupidity... - quzah

    Such pointless tricks ceased to be interesting or useful when we came down from the trees and started using higher level languages. - Salem

  9. #9
    Registered User
    Join Date
    Nov 2004
    Posts
    4
    Thanks for resolving my issue Sebastiani and andyhunter,

    Just to clarify then. So because scanf cannot look at the type of data that it is reading in, it would not be possible for any converting of data types to take place, as you said, it "does not perform implicit conversions"

  10. #10
    Handy Andy andyhunter's Avatar
    Join Date
    Dec 2004
    Posts
    540
    That would be it.
    i don't think most standard compilers support programmers with more than 4 red boxes - Misplaced

    It is my sacred duity to stand in the path of the flood of ignorance and blatant stupidity... - quzah

    Such pointless tricks ceased to be interesting or useful when we came down from the trees and started using higher level languages. - Salem

  11. #11
    Quote Originally Posted by andyhunter
    So I pose this question, could somebody explain the binary represenation of floating point numbers and exactly why the above example results in 'undefined behavior'.
    A floating point it generally is composed of
    • One sign bit
    • Some bits for the mantissa
    • Some bits for the exponent (one of them being the sign of it)

    The internal representation of the floating point numbers in C is not defined by the standard, but by the implementation. Details are given in <float.h> (range, field witdh, etc.)

    The scanf() finction is 'variadic'. It means that its prototype has an ellipse (...) as last parameter.

    This kind of function is tricky, and the expected type depends on the format parameter.

    Without an explicit cast, a variadic function performs some implicit type conversion (called 'promotion'), so that
    • a char is extended to an int
    • a float is extended to a double

    The addresses (all the scanf() variadic parameters are addresses) remain unchanged, but the function has no idea about the pointed type. This is indicated by the format.

    Here are some examples with scanf():
    • "%d" expects that the string is representing a decimal signed value, and that the destination is the address of an int
    • "%s" expects that the string is representing a sequence of characters (until the next 'blank'), and that the destination is the address of an array of char.
    • "%f" expects that the string is representing a floating point value, and that the destination is the address of a float.
    • "%lf" expects that the string is representing a floating point value, and that the destination is the address of a double.

    Meaning that if you say: "this is the address of a double", the conversion will be 'in double', fine, but the resulting value will be copied to the destination, using sizeof (double) bytes (say, 6 or 8).

    Of course, if the destination is a float (sizeof (float) is generally 4), it happens an overflow by 2 or 4 bytes, hence the undefined behaviour (UB). (Anything can happen).

    Additionally, even if the sizes were compatible, the coding will be different hence another reason for a UB.

    Maybe my sig makes more sense to you know...
    Emmanuel Delahaye

    "C is a sharp tool"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extending basic data types.
    By nempo in forum C++ Programming
    Replies: 23
    Last Post: 09-25-2007, 03:28 PM
  2. What are abstract data types
    By bhagwat_maimt in forum C++ Programming
    Replies: 4
    Last Post: 01-04-2007, 10:43 AM
  3. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  4. Replies: 4
    Last Post: 06-14-2005, 05:45 AM
  5. Using enumerated data types
    By SXO in forum C++ Programming
    Replies: 7
    Last Post: 09-04-2001, 06:26 PM