Suggestion for a function for checking fraction number

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kouisawang
    New Member
    • Dec 2009
    • 2

    #1

    Suggestion for a function for checking fraction number

    I have written a function to check if the number is fraction in either X/X or X X/X format where X is double.

    Here is the code.
    Code:
    bool IsFraction(const CComBSTR bucketSize, double &result)
    {	
    	int nToken=1;
    	HRESULT hr = S_OK;
    	CComBSTR tempBucketSize(bucketSize);
    	//Count the token. must be 2 or 3
    	wcstok(tempBucketSize.m_str, _T(" /"));
    	while(wcstok(NULL, _T(" /")))
    	{
    		++nToken;
    	}
    	
    	//If number token == 2, the number must be in the form X/X
    	if(nToken == 2)
    	{
    		CComBSTR szToken = wcstok(bucketSize.m_str, _T("/"));
    	
    		CComVariant vtNumerator = szToken;
    		hr = vtNumerator.ChangeType( VT_R8 );
    		//if szToken is not number return false
    		if(FAILED(hr) || (vtNumerator.vt != VT_R8) || (vtNumerator.dblVal < 0.0))
    			return false;
    
    		//if there's no string left or the second string is not number or it's zero, return false
    		szToken = wcstok(NULL, _T("/"));
    		CComVariant vtDenominator = szToken;
    		hr = vtDenominator.ChangeType(VT_R8);
    
    		if(FAILED(hr) || (vtDenominator.vt != VT_R8) || (vtDenominator.dblVal <= 0.0))
    			return false;
    
    		//otherwise calculate number and return true
    		result = vtNumerator.dblVal / vtDenominator.dblVal;
    		return true;
    	}
    	//If number token == 3, the number must be in the form X X/X
    	else if(nToken == 3)
    	{
    		CComBSTR szToken = wcstok(bucketSize.m_str, _T(" "));
    
    		CComVariant vtNumber = szToken;
    		hr = vtNumber.ChangeType(VT_R8);
    		//if szToken is not number return false
    		if(FAILED(hr) || (vtNumber.vt != VT_R8) || (vtNumber.dblVal < 0.0))
    			return false;
    
    		//if there's no string left or the second string is not number, return false
    		szToken = wcstok(NULL, _T("/"));
    		CComVariant vtNumerator = szToken;
    		hr = vtNumerator.ChangeType(VT_R8);
    
    		if(FAILED(hr) || (vtNumerator.vt != VT_R8) || (vtNumerator.dblVal < 0.0))
    			return false;
    		
    		//if there's no string left or the third string is not number or it's zero, return false
    		szToken = wcstok(NULL, _T(" /"));
    		CComVariant vtDenominator = szToken;
    		hr = vtDenominator.ChangeType(VT_R8);
    
    		if(FAILED(hr) || (vtDenominator.vt != VT_R8) || (vtDenominator.dblVal <= 0.0))
    			return false;
    
    		//otherwise calculate number and return true
    		result = vtNumber.dblVal + vtNumerator.dblVal / vtDenominator.dblVal;
    		return true;
    
    	}
    	else
    		return false;
    }
    It's very long but I can't think of another algorithm to deal with it. So if you have an idea to optimize it, please give me your suggestions or comments.
    Thank
    Last edited by Niheel; Aug 20 '10, 03:37 PM. Reason: please use code tags to display code
  • newb16
    Contributor
    • Jul 2008
    • 687

    #2
    Is 1.25 3.67/0.87 a fraction too, like 1 1/4 is ? If yes then ok, without decreasing number of checks it probably can't be reduced. What is VT_R8, btw?

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      1 1/4 is not a fraction. It's a mixed number. The actual number is 5/4 which is a rational number.

      1.25 3.67/0.87 is incorrect syntax. The 3.67/0.87 is a real number.

      Note that 5/4 maps to 5.0/4.0 making the rational numbers a subset of the real numbers.

      If you use the form X/X where X is a floating point number, you will have a correct representation.

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        kouisawang ...

        What precise forms do you need to recognize as fractions?
        Code:
        100          whole number (implied denominator of 1)
        1/4          ratio of integers
        0.45         decimal fraction (denominator implied by number of digits)
        2.67         mixed number (decimal fraction)
        2 1/2        mixed number (ratio, whitespace separator)
        2-1/2        mixed number (ratio, dash separator)
        1.5/7.8      ratio of real numbers
        1.2 1.5/7.8  funky mixed number
        4,5          European decimal point
        How many ways do you need to support negative numbers?
        -100, -1/4, 1/-4, -2 1/2, -(2 1/2), etc

        Comment

        • kouisawang
          New Member
          • Dec 2009
          • 2

          #5
          My intention is to have X/X and X X/X as a valid input format. X is double. however, it only supports positive number. Maybe using "fraction" is not right coz I do count numerator number with decimal point as valid input but ... you get my intention.
          btw, vt_r8 is a double variant type

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            You might consider a VT_I4 or a VT_UI4 rather than a
            VT_R8 for your VARIANT.

            You can always create a X X/X from a X/X and you can convert an input X X/X to an X/X. So the common format X/X seems you best bet.

            Further, numerators and denominators are integers and not reals. Hcne, I recommend the VT_I4 or for positives only, a VT_UI4.

            Comment

            Working...