delete me
delete me

Reputation: 65

How to find if an Integer has letters in its hex representation

I am trying to write a method in C++ which determines if an integer has letters in its hex representation using stream manipulators without using any for loop. One way could be to use getline and do some math. Can someone provide hints on the kind of computation required?

I appreciate your helps or using the Circular Arithmetic , But I am looking for something which does not iterate over the string

Upvotes: 1

Views: 607

Answers (11)

user8152951
user8152951

Reputation: 1

You can first store a hex representation in the stringstream and try to convert it to a decimal representation. If it fails to convert, then we can say that letters are present in the given integer

    stringstream myStream;
    int myInt;
    cin>>myInt;
    myStream<<hex<<myInt;
    myStream>>dec>>myInt;
    cout<<myStream.fail()<<endl;

Upvotes: 0

Ylisar
Ylisar

Reputation: 4291

Your requirements are very weird, so it's hard to give a correct answer. All the solutions so far seems to either iterate ( although some inside std functions ), or work with a straight up integer, which seems to go against your requirements? "hex representation" suggests to me that you have the number in the form of a string. If this is the fact then not using for loops(?) & forcing us to use stream manipulators makes it a no go. If the representation is in form of a ascii string, and we're not allowed to iterate, then one solution which doesn't require neither iteration nor conversion ( which likely will iterate in itself ) can make use of the fact that all alpha numeric chars have at least one of the 2 MSBs set:

#include <iostream>
#include <string>
#include <cassert>
#include "boost\cstdint.hpp"
union StrInt
{
    boost::uint64_t val;
    char str[ sizeof( boost::uint64_t ) ];
};

int main()
{
    std::string someString("A9999999" );
    StrInt tmp;
    assert( someString.size() <= sizeof( tmp.str ) );
    memcpy( tmp.str, &someString[0], someString.size() );
    std::cout << !!( tmp.val & 0xC0C0C0C0C0C0C0C0ul ) << std::endl;
}

Upvotes: 2

James Kanze
James Kanze

Reputation: 153909

Using the stream manipulators, something like:

bool
hasAlphaInRepresentation( unsigned number )
{
    std::ostringstream s;
    s << std::hex << number;
    std::string str = s.str();
    return std::find( str.begin(), str.end(), IsAlpha()) != str.end();
}

would do the trick. (I'm assuming that you have an IsAlpha functional object in your toolbox. If not, it's fairly straightforward to implement, and it's always useful.)

Of course, if the only requirement were no loop:

bool
hasAlphaInRepresentation( unsigned number )
{
    return number != 0
        && (number % 16 > 9 || hasAlphaInRepresentation( number / 16 ));
}

:-)

Upvotes: 1

gwiazdorrr
gwiazdorrr

Reputation: 6329

Using C++ ostringstream and string:

bool hasHexDigits(int number)
{
    std::ostringstream output;
    output << std::hex << number;
    return output.str().find_first_of("abcdefABCDEF") != string::npos;
}

EDIT: other solution, without using streams. It's better performance (no branches) and memory wise (no allocations), but may be too advanced for your "homework":

template<int I> struct int_to_type
{
    static const int value = I;
};

inline bool __hasHexCharacters(int number, int_to_type<0>)
{
    return false;
}

template <int digitsLeft>
inline bool __hasHexCharacters(int number, int_to_type<digitsLeft>)
{
   return ((number & 0xF) > 9) | __hasHexCharacters(number >> 4, int_to_type<digitsLeft-1>());
}

inline bool hasHexCharacters(int number)
{
    return __hasHexCharacters(number, int_to_type<2 * sizeof(int)>());
}

Upvotes: 6

Luka Rahne
Luka Rahne

Reputation: 10447

You can do someting like (only logic operation and one substraction)

 bool has_letters(int num)
 {   
      if(num < 0) num = 0- num; //abs value
      unsigned char * c;
      c = (unsigned char * )(& num)
      for(int i=0;i<sizeof(int),i++)
      {
           if(((c[i] & 0xf) > 0x9) || ((((c[i]>>4) & 0xf) > 0x9) )
               return true;
           //or you can use precomputed table
           //if(table[c[i]])
           //     return true;
      }
      return false;
 }

Trick is that binary representaion of string is allready hex (almost) you just need to chek each nibble

Upvotes: 0

Chris Parton
Chris Parton

Reputation: 1054

Another method using stringstream:

std::stringstream ss;
std::string str;
std::string::iterator it;
bool hasChar = false;

// Use the hex modifier to place the hex representation of 75 into the
// stream and then spit the hex representation into a string.
ss << std::hex << 75;
str = ss.str(); // str contains "4b"
it = str.begin();

// Check for characters in hex representation.
while (!hasChar && it != str.end())
{
    if (isalpha(*it))
        hasChar = true;
    ++it;
}

Upvotes: 1

bdonlan
bdonlan

Reputation: 231113

// Assumes 32-bit int. Computing the mask based on UINT_MAX is left as an
// exercise for the reader.

int has_hex_alpha(unsigned int num) {
    return !!((num & (num << 1 | num << 2)) & 2290649224);
}

Upvotes: 2

Mariy
Mariy

Reputation: 5914

bool func(int num) {
    while ( num > 0 ) {
         if ( num % 16 > 9 ) return true;
         num /= 16;
    }
    return false;
}

Upvotes: 1

Vijay
Vijay

Reputation: 67221

sprintf(string,"%x",<your integer>);

will give your hexa decimal number.

so after this,check if your string has any alphabets below using some string functions available.

a,b,c,d,e,f

Upvotes: 2

Felice Pollano
Felice Pollano

Reputation: 33252

divide the int by 16 until you reach zero. Each time check the remainder, if it is > 9 hex contains letters.

Upvotes: 5

Anthony Blake
Anthony Blake

Reputation: 5348

Perhaps use regex?

regex rgx("[A-Za-z]+");
smatch result;    
if(regex_search(integer_string, result, rgx)) { 
  cout << "There is alpha chars in the integer string" << endl;
}

Upvotes: 1

Related Questions