chipKIT® Development Platform

Inspired by Arduino™

long long int issues

Created Sat, 11 Jan 2014 11:59:57 +0000 by pito


pito

Sat, 11 Jan 2014 11:59:57 +0000

Hi, I've been trying to print long long int somehow, no luck yet.

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

void setup() 
{
  Serial.begin(115200);
  while(!Serial);  // Wait for the PC to open the port
  delay(3000);
}

void loop()  {	
	
	char buf [25];
	long long int aaa;
	long int n;
	
	aaa = 123456789012345LL;
	Serial.println(sizeof(aaa));
	Serial.println(sprintf(buf, "%ld", aaa));
	Serial.println(sprintf(buf, "%lld", aaa));
	Serial.println(sprintf(buf, "%LLd", aaa));
	Serial.println(itoa(aaa, buf, 10));
	Serial.println(ltoa(aaa, buf, 10));
	n = aaa / 555555;
	Serial.println(n);
	
	while(1);
}

That prints out:

8
11
15
11
-2045911175
-2045911175
222222442

So the sizeof is 8 and 222222442 is ok as well. How to get it printed, however?


majenko

Sat, 11 Jan 2014 12:03:46 +0000

You won't ever be able to print a long long using Serial.println as that casts all integer values to a long. If you print out your string buffer (the results of the sprintf) I'll bet it works, but you can't pass a long long to a function that takes a long and expect it to work.


pito

Sat, 11 Jan 2014 12:12:29 +0000

grrh... I messed up with sprintf in print as arg.. :oops: This is the correct version and at least one option works:

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

void setup() 
{
  Serial.begin(115200);
  while(!Serial);  // Wait for the PC to open the port
  delay(3000);
}



void loop()  {	
	
	char buf [25];
	long long int aaa;
	long int n;
	
	aaa = 123456789012345LL;
	Serial.println(sizeof(aaa));
	sprintf(buf, "%ld", aaa);
	Serial.println(buf);
	sprintf(buf, "%lld", aaa);
	Serial.println(buf);
	sprintf(buf, "%LLd", aaa);
	Serial.println(buf);
	Serial.println(itoa(aaa, buf, 10));
	Serial.println(ltoa(aaa, buf, 10));
	n = aaa / 555555;
	Serial.println(n);
	
	while(1);
}
8
-2045911175
123456789012345
-2045911175
-2045911175
-2045911175
222222442

Thnx!


majenko

Sat, 11 Jan 2014 12:18:38 +0000

The only wayt to print a long long is to preformat it into a string with %lld. You could always do manual character-by-character printing of it, starting with the highest denomination of number, dividing your number by it, printing that, result, dividing your denominator by 10 and repeating until you run out of demominator. Might be lighter weight than using sprintf. For signed values check if it's <0, print a - if it is, and do the above method on the absolute value.


Jacob Christ

Wed, 12 Feb 2014 15:20:26 +0000

You should also be careful of the size of your buffer. Your long long is 25 chars and so is buf. You, however need your buf to be 26 chars to make room for the null termination of the string.

Jacob


majenko

Wed, 12 Feb 2014 15:38:06 +0000

This is a local addition to the Print class I have:

void Print::printf(const char *fmt, ...) {
    va_list va;
    va_start(va, fmt);
    char temp[1];
    uint32_t slen = vsnprintf(temp, 1, fmt, va);
    va_end(va);
    char out[slen + 2];
    va_start(va, fmt);
    vsnprintf(out, slen+1, fmt, va);
    va_end(va);
    print(out);
}

It basically adds printf() to anything that inherits Print (so all the Serial, LCD, etc classes).

It find it incredibly useful, but it's not wonderfully efficient.

It renders the string twice - first to work out how much room the string needs, and then a second time to actually render it into a buffer that's sized to fit the string.

It's so nice being able to use:

Serial.printf("The time is: %02d:%02d:%02d\n", hours, minutes, seconds);

;)


Andersan

Fri, 05 Dec 2014 05:49:35 +0000

Hi, I've been trying to print long long int somehow, no luck yet.


Gary Freegard

Thu, 14 May 2015 14:51:11 +0000

Hi

I too had the same problem, so created a new method based on printNumber (in UECIDE\cores\chipKIT\api\Print.cpp)

void PrintLong(unsigned long long n, uint8_t base, uint8_t dp)
{
unsigned char buf[8 * sizeof(long long)]; // Assumes 8-bit chars.
unsigned long i = 0;

	if (n == 0)
	{
		Serial.print('0');
		return;
	}
 
	while (n &gt; 0)
	{
		buf[i++] = n % base;
		n /= base;
	}

	for (; i &gt; 0; i--)
	{
		if (i==dp){
			Serial.print(".");
		}
		Serial.print((char) (buf[i - 1] &lt; 10 ?
					'0' + buf[i - 1] :
					'A' + buf[i - 1] - 10));
	}
}

Obviously if base 10 is always the required base then base would be replaced with a constant and in the Serial.print the 'A' +... could be removed.

Hope this helps

Gary