Hallo everybody.
I want to print an long with separators "," and ".". For example, I want to show on LCD the number 1234567 as "1,234.567". How would I go about doing this? Thanks very much.
For example, I want to show on LCD the number 1234567 as "1,234.567".
How did YOU determine where to put the comma? How did you determine where to put the dot?
Did either decision depend on dividing by 1000?
Output is fequency in Hz for frequency from 1MHz to 6GHz.
If freq > 10MHz then output is "XX,XXX.XXX Hz"
If freq > 100MHz then output is "XXX,XXX.XXX Hz"
If freq > 1000MHz then output is "XXXX,XXX.XXX Hz"
else
output is "X,XXX.XXX" for freq < 10Mhz
Other than the order of operations being wrong (start with the largest value and work down), you seem to know what you need to do.
Am I missing something?
PaulS:
Am I missing something?
Yes. You are missing two things:
(1) How to actually be helpful
(2) How to be polite
Yes. You are missing two things:
(1) How to actually be helpful
(2) How to be polite
If (1) means failing to provide the code, I get PAID for that. I prefer to teach people to think for free.
As for (2), point out just EXACTLY where I am being less than polite.
ok2fug:
Output is fequency in Hz for frequency from 1MHz to 6GHz.
If freq > 10MHz then output is "XX,XXX.XXX Hz"
If freq > 100MHz then output is "XXX,XXX.XXX Hz"
If freq > 1000MHz then output is "XXXX,XXX.XXX Hz"
else
output is "X,XXX.XXX" for freq < 10Mhz
The following code is a small utility I wrote to display CPU speed in Linux. But the parts highlighted in blue show how to scale the number and display a suffix such as "Hz" or "MHz" or "GHz"... this may be of some help to you.
/***********************************
* cpus.c wednesday 30 april 2014
***********************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
const char govinfo = "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor";
const char *cpuinfo = "/proc/cpuinfo";
const char *target = "cpu MHz\t\t: ";
const char *hertz[] = { "", "k", "M", "G", "T", "P", "E" };
FILE *fp = NULL;
char *buf = NULL;
char *ptr = NULL;
uint8_t allflag = 0;
uint8_t freqflag = 0;
uint8_t govflag = 0;
uint8_t hzflag = 0;
uint32_t x = 0;
uint32_t y = 0;
uint32_t multiplier = 0;
uint32_t cores = 0;
uint32_t targlen = 0;
uint32_t fsize = 0;
uint32_t precision = 0;
double *freq = NULL;
double re_alloc = NULL;
double avg = 0;
const char strip_path (const char str) {
** uint32_t ofs;
** ofs = strlen (str);
** while (ofs--) {**
__ if (* (str + ofs) == '/' || * (str + ofs) == '\') {__
** break;**
** }**
** }**
** ofs++;**
** return (str + ofs);**
}
int main (int argc, char *argv[]) {
__ opterr = 0; /* suppress getopt's built in error messages /__
__ precision = 3; / default precision /__
** while ((x = getopt (argc, argv, "afghp:")) + 1) {*
** switch (x) {**
** case 'a' : {**
** allflag = 1;**
** break;**
** }**
** case 'f' : {**
** freqflag = 1;**
** break;**
** }**
** case 'g' : {**
** govflag = 1;**
** break;**
** }**
** case 'h' : {**
** hzflag = 1;**
** break;**
** }**
** case 'p' : {**
** precision = atoi (optarg);**
__ if ((precision > 9)) { /* sanity check /__
** precision = 3;*
** }**
** break;**
** }**
** case '?' : {**
** if (optopt == 'p') {**
** fprintf (stderr, "%s: option -%c requires an argument\n\n", strip_path (argv[0]), optopt);**
** return 1;**
__ } else { /* print out simple help /__
** fprintf (stdout,*
** "\n"**
** "Usage: %s [options]\n"**
** " -a display all cores separately\n"**
** " -f display frequency only\n"**
** " -g display governor in use\n"**
** " -h display in hertz (don't scale)\n"**
** " -p display precision n (default:3)\n"**
** "\n",**
** strip_path (argv[0])**
** );**
** return 1;**
** }**
** }**
** default : {**
** fprintf (stderr, "\n%s: switch/case/default: should never see me\n", strip_path (argv[0]));**
** return 1;**
** }**
** }**
** }**
** fp = fopen (cpuinfo, "rb");**
** if (fp == NULL) {**
** fprintf (stderr, "%s: open %s for read failed\n", strip_path (argv[0]), cpuinfo);**
** return 1;**
** }**
__ while (!feof (fp)) { /* fseek/ftell doesn't work on /proc files /__
** fgetc (fp);*
** fsize++;**
** }**
** fclose (fp); fp = NULL;**
__ ptr = buf = (char ) malloc ((fsize + 1) * sizeof (char));__
** if (!buf) {*
** fprintf (stderr, "%s: malloc failed (buffer)\n", strip_path (argv[0]));**
** return 1;**
** }**
__ freq = (double ) malloc (1 * sizeof (double));__
** if (!freq) {*
** fprintf (stderr, "%s: malloc failed (freq)\n", strip_path (argv[0]));**
** return 1;**
** }**
** fp = fopen (cpuinfo, "rb");**
** if (fp == NULL) {**
** fprintf (stderr, "%s: open %s for read failed\n", strip_path (argv[0]), cpuinfo);**
** free (buf); buf = NULL;**
** free (freq); freq = NULL;**
** return 1;**
** }**
** fread (buf, sizeof (char), fsize, fp);**
** fclose (fp); fp = NULL;**
** targlen = strlen (target) - 1;**
** for (x = 0; x < fsize; x++) {**
__ if ((* (buf + x) | 0x20) == (* (target + y) | 0x20)) { /* ignore case /__
** if (y == targlen) {*
** ptr = buf;**
** ptr += x;**
__ * (ptr + targlen) = 0;__
__ * (freq + cores) = atof (ptr) * 1.0e6f; /* MHz. -> Hz. /__
** multiplier = 0;*
** if (hzflag) {**
** precision = 0;**
** } else {**
__ while (* (freq + cores) > 1000.0) {
* (freq + cores) /= 1000.0;
** multiplier++;**
** }**
** }**
__ avg += * (freq + cores++);
__ /* allocate storage for next core freq /__
re_alloc = (double ) realloc (freq, (cores + 1) * sizeof (double));
** freq = re_alloc;
** if (!freq) {**
** fprintf (stderr, "%s: realloc failed (freq)\n", strip_path (argv[0]));**
** free (buf); buf = NULL;**
__ /* free (freq); freq = NULL; /__
** return 1;*
** }**
** } else {**
__ y++; /* find next char of match /__
** }*
** } else {**
__ y = 0; /* reset find pointer /__
** }*
** }**
** for (x = 0; x < cores; x++) {**
** if (govflag) {**
** sprintf (buf, govinfo, x);**
** fp = fopen (buf, "rb");**
** if (fp == NULL) {**
** fprintf (stderr, "%s: open %s for read failed\n", strip_path (argv[0]), buf);**
** free (buf); buf = NULL;**
** free (freq); freq = NULL;**
** return 1;**
** }**
** fgets (buf, fsize, fp);**
** fclose (fp); fp = NULL;**
__ * (buf + (strlen (buf) - 1)) = 0;__
** }**
** if (!freqflag) {**
** fprintf (stdout, "%s", allflag ? "Core" : "Average of");**
** fprintf (stdout, " %d", allflag ? x : cores);**
** fprintf (stdout, "%s", allflag ? ": " : " cores: ");**
** }**
__ fprintf (stdout, "%.f", precision, allflag ? * (freq + x) : avg / cores);__
** if (!freqflag) {*
__ fprintf (stdout, " %sHz.", * (hertz + multiplier));__
** }**
** if (govflag) {**
** fprintf (stdout, " [%s]", buf);**
** }**
** fprintf (stdout, "\n");**
** if (!allflag) {**
** break;**
** }**
** }**
** free (buf); buf = NULL;**
** free (freq); freq = NULL;**
** return 0;**
}
Note: Stuff like this:
*(buffer + offset)
is the same thing as:
buffer[offset]
Hope it helps...
-- Roger
Krupski:
PaulS:
Am I missing something?Yes. You are missing two things:
(1) How to actually be helpful
(...)
You miss that part too, right?
As the problem is to write to the LCD I think you don't need to convert the result to string. So you only need to separate the parts of the number.
I did a little example that convert a static number to various parts. You can pick this idea and make it work for your case:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
long number = 1234567;
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
}
void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
//lcd.print(millis()/1000);
int numb1 = (int) (number/1000000L);
lcd.print(numb1);
lcd.print(".");
int numb2 = (int) ((number - numb1*1000000L)/1000L);
lcd.print(numb2);
lcd.print(",");
int numb3 = (int) ((number - numb1*1000000L-numb2*1000L));
lcd.print(numb3);
}
I begin to write this post before this 2 last replies.
@Krupski: Even with that 787 posts, I think you need to take a look to the rules of the forum, specially the part of posting code:
http://forum.arduino.cc/index.php?topic=97455.0
PaulS:
Yes. You are missing two things:
(1) How to actually be helpful
(2) How to be politeIf (1) means failing to provide the code, I get PAID for that. I prefer to teach people to think for free.
As for (2), point out just EXACTLY where I am being less than polite.
I get paid to teach college students electronics. I don't expect to get paid here. Here, I do it as a hobby, for fun.
As far as "failing to provide code", I don't necessarily think that giving someone pre-written code is the right course of action. It all depends on the circumstances. But, simply answering a question with another question is rarely helpful.
Concerning this particular thread, the way I would have done it is to say something like "Do you see where you put your comma and dot? The comma is at the one thousands place and the dot is at the one one-thousandths place. Therefore, if you divide the number by 1000 and count how many times you had to do that in order to reduce the number to one, that will tell you how many commas you need, and of course they go every three digits".
The way you did it is technically correct, but provides little insight into WHY it's done. Someone who is asking a question (even a ridiculously simple one) is not seeing the obvious in front of their face. We've all done that, and a little hand holding at a point like that is VERY helpful.
Of course, this is all just my personal opinion, which is worth all of 2 cents......
luisilva:
@Krupski: Even with that 787 posts, I think you need to take a look to the rules of the forum, specially the part of posting code:
Read this before posting a programming question ... - Programming Questions - Arduino Forum
I know full well to use the CODE tags.
I posted it the way I did because the CODE tags do not allow the bold or color BBcodes to be used, and I wanted to highlight certain lines.
The point of using the code tags is to make posted code readable. Is not the way I did it AS READABLE as the code tags?
Concerning this particular thread, the way I would have done it is to say something like "Do you see where you put your comma and dot?
So, when answer a question with another question, I'm being unhelpful and rude, and when you do it, it's OK. F**k you very much.
Krupski:
luisilva:
@Krupski: Even with that 787 posts, I think you need to take a look to the rules of the forum, specially the part of posting code:
Read this before posting a programming question ... - Programming Questions - Arduino ForumI know full well to use the CODE tags.
I posted it the way I did because the CODE tags do not allow the bold or color BBcodes to be used, and I wanted to highlight certain lines.
The point of using the code tags is to make posted code readable. Is not the way I did it AS READABLE as the code tags?
You can do the same that you did with your colour thing with comments. For what do you use your comments?
The thing of using code tag is to make the code more readable and (I think) to make post smaller. The thread become almost unreadable with a post that length. And more important IS A RULE! You don't have to agree with that only need to follow that.
About the "little arg" with PaulS, I think you only need to look to the number of posts that he write until this time! I have read many posts of PaulS and is a user that help many, many users. I think that he is only asking the more important question in this kind of places ("tell me what you have done until now?"), but in other way. Right?
This is one of the rare occasions where I would use a recursive solution:
Write a function that outputs a number. If the number to be displayed is less than 1000 then output it directly. If it's bigger than 1000, have the function call itself to print the number divided by 1000, then print a thousands separator, then print the number mod 1000.
Here, 'output' could mean sending the formatted text directly to the output device, or appending it to a text buffer.
Krupski:
I get paid to teach college students electronics. I don't expect to get paid here. Here, I do it as a hobby, for fun.As far as "failing to provide code", I don't necessarily think that giving someone pre-written code is the right course of action. It all depends on the circumstances. But, simply answering a question with another question is rarely helpful.
While i can somewhat understand what you're trying to say, i can't but completely disagree with that statement.
One of the best ways to help people think about what they're trying to achieve (and to show them in which direction you are thinking when facing the problem) is by asking them questions.
I've once on a forum gotten the reply from someone i helped out on a forum that with every question i asked he knew what i thought what the problem could be, and he would figure it out by himself, and then come back later on when something else was going wrong. After a few such questions he managed to solve his problems :).
In this case the poster pretty much understands what needs to happen. If he has problems with a concrete implementation, i think the "question askers" here would be glad to point to the issues in the code/help him out. It's just way nicer to see people achieve these things themselves, and not just wait for someone to do the work for them :). (and also when people solved it themselves, they usually learned more and remember it better).
There is no "simple" way to do this. My advice would be to solve the problem once, write a function to do it properly, and then you can use that function in the future.
This is @ok2fug's topic. Only that person can decide what is and is not helpful. Those of you who are arguing about what it means, in general, to be helpful have drifted off-topic.
No more off-topic bickering. The next post had better directly answer a question asked by @ok2fug or the person who made the post gets a time-out. Bear in mind that I leave this week for a much needed vacation. Any interference with my departure, no matter how slight, will be dealt with grossly out of proportion with the interference.