Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need Memory Transplant

Status
Not open for further replies.

OldVeryOld

Technical User
May 29, 2009
8
US
Old User, Needs to Remember Old Tricks
Hi,

I wrote the piece of code that follows. I hadn't touched C in years. I'd like to fill in the "blanks" that I wall-papered over to make ths work on my own. For example:

1. What is the difference between a "double" and a "long double" in terms of the range of values/accuracy?

2. I'm using the free Borland 2006 that was passed out years ago with a hundred year license. I won't change that. I need to know how to use the label and text boxes available with Borland 2006 to display numbers, and, given my interest in engineering applications, to display numbers in scientific notation without an infinite mantissa (which results from the method I employ at the end of this program to output the result). In the following code, I declare the value I use to display the result as a "double" rather than a "long double", because I could not get the "long double" type to display using the method I used with the "double" by simply setting it equal to a IND_OUT->Caption.

3. I declare some variables that I would have, in the past, declared to be integers, as doubles, out of fear that if I multiply a double or long double by an integer C might produce an integer result and set it equal to a variable I've declared as a double. (In the past I would have thought I was nuts for doing this, but I knew more then about C than I know now.)

4. Any basic flaws in what I'm doing in terms of how to make the code neater, faster to type? (I seem to spend a lot of space declaring and initializing variables.)

5. Do I need to free up the memory space associated with variables using a specific code line for any of these variables? How?

6. How do read data from text boxes? I'm probably going to need to read some numbers from text boxes if I ever turn this into a user interactive program, rather than something in which I program the values I intend to use directly into the code associated with a push-button. The numbers need to be able to accomodate scientific notation, because I'm dealing with values given by some number x 10^-12.

7. Any other useful, programming hints.

I know this is quite a laundry list, but I haven't done the C laundry in a dozen years, and the cobwebs are thick in that corner of my mental laundry room.

Thank you! (Code Follows)


Code:
//---------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop

#include "SDIMain.h"
#include "About.h"
//---------------------------------------------------------------------
#pragma resource "*.dfm"
TSDIAppForm *SDIAppForm;
//---------------------------------------------------------------------
__fastcall TSDIAppForm::TSDIAppForm(TComponent *AOwner)
: TForm(AOwner)
{
}
//---------------------------------------------------------------------

void __fastcall TSDIAppForm::FileNew1Execute(TObject *Sender)
{
// Do nothing
}
//---------------------------------------------------------------------------

void __fastcall TSDIAppForm::FileOpen1Execute(TObject *Sender)
{
OpenDialog->Execute();
}
//---------------------------------------------------------------------------

void __fastcall TSDIAppForm::FileSave1Execute(TObject *Sender)
{
SaveDialog->Execute();
}
//---------------------------------------------------------------------------


void __fastcall TSDIAppForm::FileExit1Execute(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------

void __fastcall TSDIAppForm::HelpAbout1Execute(TObject *Sender)
{
AboutBox->ShowModal();
}
//---------------------------------------------------------------------------









void __fastcall TSDIAppForm::Button1Click(TObject *Sender)
{
long double HA=0;
long double BETAMAX = 720;
long double THETAMAX = 720;
long double TMAX = 1000;
long double NDIV = 1000;
long double r = 150E-6;
long double R = 170E-6;
long double cBETA = 2*3.1415/BETAMAX;
long double cTHETA = 2*3.1415/THETAMAX;
long double Rav = (R + r)/2;
long double Rdif = (-R-r)/2;
long double RDivVal = 0;
long double RecA =0;
long double NumRator = 0;
long double NumRatorA = 0;
long double NumRatorB = 0;
long double Px = 0;
long double Py = 0;
long double Pz = 0;
long double P = 0;
long double cD=0;
long double cb=0;
long double cTc=0;
long double cth=0;
long double x = 0;
long double y = 0;
long double z = 1E-43;
long double RDiv_T1=0;
long double RDiv_T2=0;
double L = 0;
long double test;

for (cD = 1; cD <= NDIV; cD++) {
RDiv_T1= cos(asin(cD/NDIV));
RDiv_T2 = 2/(NDIV*3.1415);
RDivVal = RDiv_T1*RDiv_T2;

for (cb=0; cb < 1; cb++) {

for (cTc = 1; cTc <= TMAX; cTc++) {

for (cth = 0; cth <= THETAMAX; cth++) {

RecA = r / TMAX * 2*3.1415 / THETAMAX * r * cTc / TMAX;

NumRatorA = -1*cos(cBETA*cb)*(( Rdif*sin(cBETA*cb)+y+r/TMAX*cTc*sin(cTHETA*cth)));

NumRatorB = -1*sin(cBETA*cb)*(( Rdif*cos(cBETA*cb)+z+r/TMAX*cTc*cos(cTHETA*cth)));

NumRator = sqrt(powl(NumRatorA,2) + pow(NumRatorB,2));

Px=(Rdif)*cos(cBETA*cb)+x+r/TMAX*cTc*cos(cTHETA*cth);
Py=(Rdif)*sin(cBETA*cb)+y+r/TMAX*cTc*sin(cTHETA*cth);
Pz = z;
P = (sqrtl(Px*Px + Py*Py +Pz*Pz));


HA = HA + RDivVal*(((NumRator/(P*P)*RecA)));

test=0;
}

}

}
test=0;
}
HA=2*NDIV*HA;
L = 1.257E-6/(4.*3.1415)*HA*BETAMAX;

// I named the lable box I am using to output the result "IND_OUT",
//so I could identify it more easily when writing code.

IND_OUT->Caption=L;

}
//---------------------------------------------------------------------------
 
1. That really depends on your CPU (16, 32, or 64 bit) since the math chip is different. See the program below from Thinking in C++, 2nd Edition by Bruce Eckel on how to determine what size each is.
Code:
    //: C03:Specify.cpp
    // Demonstrates the use of specifiers
    #include <iostream>
    using namespace std;

    int main() {
      char c;
      unsigned char cu;
      int i;
      unsigned int iu;
      short int is;
      short iis; // Same as short int
      unsigned short int isu;
      unsigned short iisu;
      long int il;
      long iil;  // Same as long int
      unsigned long int ilu;
      unsigned long iilu;
      float f;
      double d;
      long double ld;
      cout
        << "\n char= " << sizeof(c)
        << "\n unsigned char = " << sizeof(cu)
        << "\n int = " << sizeof(i)
        << "\n unsigned int = " << sizeof(iu)
        << "\n short = " << sizeof(is)
        << "\n unsigned short = " << sizeof(isu)
        << "\n long = " << sizeof(il)
        << "\n unsigned long = " << sizeof(ilu)
        << "\n float = " << sizeof(f)
        << "\n double = " << sizeof(d)
        << "\n long double = " << sizeof(ld)
        << endl;
    } ///:~

2. To display numbers in text boxes, you need to convert the numbers to an AnsiString. (Note: In newer verions of C++Builder, you would want to use UnicodeStrings.) There are different functions to convert different values to AnsiStrings. For example, to convert doubles to AnsiStrings, you would want to use the FloatToStrF function.
static AnsiString __fastcall FloatToStrF(long double value, TStringFloatFormat format, int precision, int digits);

Thus
IND_OUT->Caption=L;
should become
IND_OUT->Caption=FloatToStrF(L, ffExponent, 15, 4);
This will display L in scientic notation. Since L is a double you should use 15 digit precision and I just put in 4 digits for the decimal.

Look in your help file for AnsiString methods.

3. Correct. Multiplying numbers of lesser precision with number of higher precision will result in lesser precision numbers. Thus an integer times a double will result in an integer. In C++, you can get around this by throwing the lesser precision number to a higher number.
Code:
     int Aint = 355;
     int Bint = 113;
     double Pi = (double)Aint / (double)Bint; // this will result in a double float number

4. One of the things I would do is create a function that is called by your ButtonClick function. To me this would clean things up. Also see my answer to Question 5.

5. One of the things that C++ does is free memory for variables once they go out of scope. This is one reason why you should rarely declare global variables. Declare needed variables in the function then pass them back to the calling function. All the variables you declare in TSDIAppForm::Button1Click(TObject *Sender) are freed once you exit that function.

6. All data from text boxes will be AnsiStrings. Thus you would do the reverse of Question 1; however, there is a gotcha. What would happen if you a non-numeric entry in the textbox? The answer is you would get an exception thrown if you tried to convert a non-numeric entry to a numeric one. So you either have to wrap your conversion routine in a try..catch statement or use TryStrToFloat.
Help File said:
Use TryStrToFloat to convert an AnsiString, S, to a floating-point value. S must consist of an optional sign (+ or -), a string of digits with an optional decimal point, and an optional mantissa. The mantissa consists of 'E' or 'e' followed by an optional sign (+ or -) and a whole number. Leading and trailing blanks are ignored.

The DecimalSeparator global variable defines the character that must be used as a decimal point. Thousand separators and currency symbols are not allowed in the string. If S doesn't contain a valid value, TryStrToFloat returns Default.

TryStrToFloat places the result in Value, and returns true if the conversion was successful, false
otherwise.
Code:
     AnsiString In_Out_Str = IND_OUT->Caption;
     if (!TryStrToFloat(In_Out_Str, L)) // There is an error
     {
          MessageDlg("You do NOT have a valid number!", mtError, TMsgDlgButtons() << mbOK, 0);
          // Do something about it here
      }
7. I would look at Thinking in C++ 2nd Edition by Bruce Eckel for a refresher/update course on C++.



James P. Cottingham
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top