Connect with us

FLOAT and DOUBLE trouble

Discussion in 'Microcontrollers, Programming and IoT' started by lady_krizzie, Sep 7, 2012.

  1. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    Hi... I'm trying to make a calculator using Hyperterminal, AT90USB647, RS232 and Atmel Studio 6. I want it to display the decimal places (i.e. 5.1, 2.332 , and so on..). ... At first I make all answer as float, so all output answer became '?'. So I separate the '/' operation.I put float and double but its output answer is still '?',and other arithmetic operations functions correctly. How can I make the calculation right?

    Code:
    #include <avr/io.h>
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define F_CPU 8000000UL
    
     /* UART library included here*/
    
    char string [16];
    char num1[16] = {};
    char num2[16] = {};
    int number1 = 0;
    int number2 = 0;
    char operand;
    int answer = 0;
    float fans = 0;
    char foo;
    
    
    int main(void)
    {
    	//hw_lcd_init();
    	USART_Init(51);
    	
    	stdout = &uart_output;
    	stdin  = &uart_input;
    	
    	int i = 0, j=0, k=0;
    	int c;
    	do
    	{
    		printf("\n\n\tHello\n\n\n");
    		printf("Enter operands: \n");
    		scanf("%s", string);
    		//lcd_gotoxy(0,0);
    		//lcd_puts(foo);	
    		printf("Equation:	%s\n", string);
    		
    		
    
    			{
    				for (i=0; i<strlen(string); i++)
    				{
    					if (isdigit(string[i]))
    						num1[i] = string[i];
    					else
    						break;
    				}
    				number1 = atoi(num1);
    	
    				operand = string[i];
    	
    				i++;
    				k = 0;
    			
    				for (j=i; j<strlen(string); j++)
    				{
    					if (isdigit(string[j]))
    						num2[k] = string[j];
    					else
    						break;
    					k++;
    				}
    				number2 = atoi(num2);
    			}
    			
    		
    	
    			switch (operand)
    			{
    				case '+':
    					answer = number1+number2;
    					break;
    				case '-':
    					answer = number1-number2;
    					break;
    				case '*':
    					answer = number1*number2;
    					break;
    				case '/':
    					if (number2==0)
    					{
    					answer= number2;
    					}
    					else
    					fans = (float)number1/ (float)number2;
    					break;
    			}
    	
    		
    		printf("number1: %d\n", number1);
    		printf("number2: %d\n", number2);
    		
    		if (operand == '/')
    			printf ("\nAnswer is: %f\n", fans);
    		else
    			printf("\nAnswer is: %d\n", answer);
    	
    		printf("\nNew Operand, enter an expression twice");
    		scanf("%d" , &c);
    		
    	
    	}
    	while( (getchar()!='n') && (getchar()!='N') );	
    	return 0;
    }
     
  2. Raven Luni

    Raven Luni

    798
    7
    Oct 15, 2011
    Youre getting an error because your variables are declared as ints not floats. If you change them remember to use atof instead of atoi
     
  3. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    It won't solve the problem. I just figured that Atmel 6 doesnt have a library for float.
     
    Last edited: Sep 7, 2012
  4. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,222
    2,696
    Jan 21, 2010
    Then you may have to use integers with an assumed decimal point.

    If your integers are 2 byte, they go from -32768 to 32767. But you can treat them as if they got from -327.68 to 327.67.

    Adding and subtracting work fine, however you have to be careful with multiplying and dividing.

    Also you'll need to be a bit clever with your I/O of the numbers.
     
  5. Harald Kapp

    Harald Kapp Moderator Moderator

    9,416
    1,925
    Nov 17, 2011
    If not absolutely necessary, avoid float on a small µC if it doesn't have a dedicated floating point unit. Even if a floating point library is available, it will be a software emulation and run very slowly.
     
  6. Raven Luni

    Raven Luni

    798
    7
    Oct 15, 2011
    Steve is right. What you want to use are fixed point numbers. But what you are using is a binary point rather than a decimal point. The easiest way is to use the largest int size available. What you must remember is that after a multiplication you have to right shift the result. Here is simple example. Take a 32 bit int with 16 bits each for integer and fractional parts. perform (2 * 0.5). With this representation it would really be 128 * 512 = 65536. To reach the correct value of 1 (or 256) you have to right shift by 16.

    To divide, multiply by the reciprocal of the divisor.
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-