|
Granted. In this case he is not getting the results he is seeking float may be the problem...
|
|
|
|
|
Michael_Davies wrote: float may be the problem. No, the problem is he does not understand how float values are represented in computers.
|
|
|
|
|
There is no decrementation, you just need to understand What Every Computer Scientist Should Know About Floating-Point Arithmetic[^].
What you should do to transfer the data (via serial or internet) is to transfer the exact bytes of the data, rather than trying to convert them to something else. So take the address of the number, cast that to an unsigned char* and send the four bytes thus pointed at. This will ensure that your receiver will get the exact data that you send.
|
|
|
|
|
Still learning how to code wrote: flResult ends up as 4.00000 which is correct That is not correct. The problem occurs when assigning 0.04 because the binary representation of floating point values can be slightly inexact. In your case flTest will be set to the value 0.0399999991. The following multiplication by 100 will not add another error so that flResult becomes 3.99999991.
Because there is no rounding when casting floating point values to integers, the result is 3. To avoid this, you can add 0.5 before casting:
ucResult = (unsigned char)(flResult + 0.5f);
Note that the above is for positive numbers only. With negative numbers, 0.5 must be subtracted.
|
|
|
|
|
First of all, apologies for not replying earlier !
WOW, I didn't think that a few lines of code could provoke so much discussion !!!
The technique that I am trying to employ is between a PC and an Arduino (via Com port - actually USB). I used it a few years ago to transfer floating point numbers, but in the OPPOSITE direction and it worked perfectly.
Anyway, thank you all for your comments - I am amazed that the "error" is actually in the assignment as pointed out by Jochen. In this particular application, the floating point numbers will be quite small, so I think that I'll have to go for the 4 byte transfer method to maintain accuracy - but I'll be doing a lot of testing !! Thank you all once again !
Doug
|
|
|
|
|
If you need to transmit a float value on the net then do transmit it, that is send its binary representation (e.g 4 bytes for a float, 8 for a double).
|
|
|
|
|
That's assuming that you have similar processors at both ends of the connection. While big-endian systems are rare these days, they're not non existent. Furthermore, be careful when going between 32-bit and 64-bit systems. On my x86 linux boxes, a long is 4 bytes, whereas on a x86_64 they're 8 bytes, x86 long-double is 12 bytes and x86_64 its 16.
|
|
|
|
|
|
I am not seeing this issue.
I get 4 for unResult.
Do you have your floating point options set correctly in the compiler?
In visual studio, select properties on your C project. Expand the projects setting out for "c/C++->Code Generation" and set the option for "Floating Point Model" to Precise(/fp:precise).
|
|
|
|
|
I have a combobox in a mfc application. I created it at runtime with following code -
if (!m_sortBox.Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, rect, this, eSortBox))
return FALSE;
Now the requirements, if user is selecting an item from combobox like , if combo box have focus & user is pressing up/down arrow key, it should NOT update the data.
If user is pressing enter key after selecting a item, it should update data.
So i didn't handled OnSelchange here.
For enter key requirement, I checked enter key event in preTranslateMsg & checking if combo box have focus, it should trigger the function, who will eventually update the data.
if (pMsg->message == WM_CHAR && pMsg->wParam == VK_RETURN)
{
CWnd pActiveWnd = CWnd::FromHandle(GetFocus()->GetSafeHwnd());
CWnd pcbSortBoxWnd = CWnd::FromHandle(m_sortBox.GetSafeHwnd());
//If sort combo box has focus and user press Enter key, it should trigger OnComboSelChange event
//Eventually it will update the data.
if (pcbSortBoxWnd == pActiveWnd)
OnSortChange();
}
I also handled ON_CBN_CLOSEUP(eSortBox, OnSortChange)
So that mouse functionality will work(because with mouse, data should get update)
Now my logic is working but its crashing in some cases.
Like - If I press Alt + Down arrow key, which will expand combobox, I select an item(with help of arrow keys) and press enter.
Sometimes its getting crash.
please help me out.
Regards,
Amrit Agrawal
|
|
|
|
|
Amrit Agr wrote: Sometimes its getting crash Then you need to use your debugger to try and identify where the crash occurs, and why.
|
|
|
|
|
I tried to isolate the problem
It appears when a global variable is declared at the .h header file and the header file is called from 2 or more cpp files, as example I tried to link the following 3 files:
#pragma once
#include <stdio.h>
int variable;
#include "header.h"
void main()
{
variable=0;
}
#include "header.h"
void change()
{
variable=0;
}
Then the following LINKER error appear:
1>source2.obj : error LNK2005: redefined "int variable" (?variable@@3HA) in main.obj
The only way I could "fix" the problem is in project properties> linker>command line add:
/FORCE:MULTIPLE
Unfortunately it can hide possible problems
I think the problem is that the #pragma once does not work.
It does not work also to define a constant and use #ifndef to avoid reading 2 times.
|
|
|
|
|
You should declare it extern in the header, and define it in only one of your .cpp
files. Something like:
#pragma once
#include <stdio.h>
extern int variable;
#include "header.h"
int variable = 0;
void main()
{
}
|
|
|
|
|
It works!
It must be "declared" as extern in the header file one time and "defined" one time as you said in the main.cpp.
It must not be defined again at any other file (source.cpp) unless extern is added
The dafault value must be placed in the main.cpp as you wrote
I do not like the solution very much because I have to be careful when changing the name of the variable to do in both sides.
|
|
|
|
|
Member 11988283 wrote: It must not be defined again at any other file (source.cpp) unless extern is added You do not need to do that, as it is declared in the header.
Member 11988283 wrote: I do not like the solution very much because ... Sorry, but you have no choice if you want to use global variables; which is something you should really avoid.
|
|
|
|
|
I tried it by delete from the .cpp but unfortunately following error appeared:
error LNK2001: external symbol "int variable" (?variable@@3HA) unresolved
I agree with you, there is not other choice. I do not like also global variables so I had not that problem before 
|
|
|
|
|
Member 11988283 wrote: I tried it by delete from the .cpp Why? I showed you what to do and explained where it should be declared: in the header. And where it should be defined: in one .cpp file.
|
|
|
|
|
Another way to solve this problem (and have only one place where the variable is defined):
In foo.h:
#ifdef DEFINE_GLOBALS
#define GLOBAL
#define INIT(x) = (x)
#else
#define GLOBAL extern
#define INIT(x)
#endif
GLOBAL int globalInt INIT(42);
In foo.cpp (and ONLY in foo.cpp):
#define DEFINE_GLOBALS
#include "foo.h"
In other source files:
#include "foo.h"
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
I don't see the advantage of this over the usual approach (the one suggested by Richard).
|
|
|
|
|
The problem with this is that everything is hidden by those #define s so as to make it less easy to understand when looking at the source code.
|
|
|
|
|
It can be confusing if encountered for the first time, but if this is the agreed idiom in your team, it ensures that all definitions occur only once. This in turn eliminates all possibilities of mismatches between declarations and definitions.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
The basis for the error is that building an EXE constitutes compiling and linking.
Compilation - Every CPP file, also called a translation unit or compilation unit, is compiled separately to form OBJ files.
Linking - All the OBJ files are linked together to become the EXE.
In your case, during compilation, every OBJ file will contain a symbol called int variable .
This means the compilation of all units are successful.
But when the linker takes all the OBJ files to create an EXE, it finds the same symbol in all translation units and so it becomes ambiguous to it as to which symbol to use.
Having said this, there are two things that you may want to do with global variables.
First
You may want to use a global variable that is shared between all translation units.
This is the answer that you've gotten so far.
The global variable declaration must happen only once so that the linker only finds one symbol for the variable and links all other extern references to that symbol.
Second
You may want to use the same name for the global variable in each translation unit.
For this to happen, declare the global variable as static - static int variable;
This forces the compilation process to not share the symbol among other translation units.
For more information refer to this link - Types of Linkage[^]
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
«_Superman_» wrote: For this to happen, declare the global variable as static - static int variable; Which means they are not global.
|
|
|
|
|
They are definitely not local.
They are global to the functions in that file.
They are local to that file.
If you look at the assembly output, they are created as global variables.
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
«_Superman_» wrote: They are definitely not local. Yes they are; go back to the link in your original post and read it again.
«_Superman_» wrote: They are global to the functions in that file. The term 'global' here is confusing the issue.
«_Superman_» wrote: They are local to that file. So which is it?
«_Superman_» wrote: If you look at the assembly output, they are created as global variables. Again you misunderstand the term 'global'.
|
|
|
|