I've taken the link provided above (about cumulative average) as an inspiration to calculate the average incrementally, in a way that no intermediate value gets larger than about three times the maximum absolute value being added. Since I wasn't sure about various effects, such as the current average going negative, I added some test code and asserts to verify it actually works as intended. See the code below:
The last line is how it's used. For passing the values, you can pass any pair of iterators that delimit the range, including simple pointers (as I've done here), provided that these iterators can be incremented and dereferenced. In this example, the cumulative average does go negative a few times, and the total sum adds up to 625, way above the maximum a char can hold.
Note that you may not use a signed type for n_values: I originally used a signed type, but then found that this led to some nasty signed/unsigned conversion effects. You could probably get rid of that with proper casting though.
P.S. these are the formulas I've used:
The general idea is to have two values that correspond to the rounded average, and the remainder of the division, like this:
Cum_avg(n) := sum(x1 ... xn) \ n
Cum_rem(n) := sum(x1 ... xn) % n
These two values then fulfil the follwing equation:
sum(x1...xn) = n*Cum_avg(n) + Cum_rem(n)
The values for the next iteration are then calculated based on the previous values like this:
I've used a helper variable called addendum to hold the divisor of the second term. This term is just a sum of three values that are going to be in the normal value range, so the worst that can happen here is an overflow of that term. I still suspect that this can happen under certain circumstances, so the calculation of addendum may need some reworking!
The remainder of the next iteration is then simply the remainder of the division of addendum:
Cum_rem(n+1) := addendum % (n+1)
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
As suggested by some comment on the link you posted (thank you) the problem seems to be in the fgets function. It is storing senseless data in buff for Release, and then the std::string constructor can't make sense of it.
I'm working on a small libarary that will parse and modify a certain type of configuration file. As suggested by wise people (I think) I'd like to hide away the implementation and offer the user a set of functions to use the library.
I have questions mainly philosophical or concerning style. I'll put here my idea and it'd be very nice to get your opinions on it.
//open and parse a file
// empty string "" if succesful
// error description if not
std::string openConfigFile (const std::string & fileName);
//check if a symbol is defined
bool isDefined (const std::string & symbol);
//how many values are assigned this symbol
int howMany (const std::string & symbol);
//get first (or only) value assigned to the given symbol
bool getBool (const std::string & symbol);
int getInt (const std::string & symbol);
double getDouble (const std::string & symbol);
std::string getString (const std::string & symbol);
//get all the values assgined to the given symbol
std::vector <bool> getAllBool (const std::string & symbol);
std::vector <int> getAllInt (const std::string & symbol);
std::vector <double> getAllDouble (const std::string & symbol);
std::vector <std::string> getAllString (const std::string & symbol);
- Does this design make sense in general?
- Do I put it all whithin a namespace?
class ConfigNode : public ConfigEntry
typedef std::map<std::string,std::shared_ptr<ConfigEntry> > EntryMap;
class ConfigValue : public ConfigEntry
class StringConfigValue : public ConfigValue
class IntConfigValue : public ConfigValue
class ConfigFile : public ConfigNode
This way the EntryMap can hold std::string, int and nested ConfigNode objects.
Chief Architect - Powel AS
Projects promoting programming in "natural language" are intrinsically doomed to fail. Edsger W.Dijkstra
If you're using this in C++ only, seems ok (let alone the preferences).
However, I'd do this:
- no namespace exports; be wary of linker decorations
- export just the needed functions, not all (i.e. the "public" interface)
- separate helpers from actors (i.e openConfigFile, isDefined vs getBool, getInt)
- do not return std::string or others from functions; rather, return just simple testable values (int, bool) and change to
bool openConfigFile(const std::string& filename, std::string& result); (or std::string* result)
- if you'll get this used in other places, favor a C-like interface and do the plumbing code, such as
BOOL WINAPI OpenConfigFileA(LPCSTR fileName, LPSTR* result);
or use VARIANTs is needed in VBS.
- or favor the COM-like exports with just structs with virtual pure functions and DllGetClassObject-like creators.
There are many things to consider. I'm using sometimes even paper and pen to weight all these.
Don't convert console apps, rather follow this short list:
1. Make sure key logic is not in same file as main.
2. Create a dialog app using Visual Studio
3. Add files from step 1
4. Hook up functionality
Of course 4 is the complicated part since how Windowed apps work is different from Console. As previously suggested, if you don't know how windowed apps work, get educated. Petzold isn't a bad starting point, though will only take you so far.
Just another homework, no effort from poster, just "I can't do it" and a link.
We're supposed to invest time and effort to offer you solutions for free, in our time, so you can get an A and forget about C++ or something? RTFM.