Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

New Bases, Part 1


January 2002 C++ Experts Forum/Conversations


Copyright 2002, Jim Hyslop and Herb Sutter

Things were very quiet in the Ballroom.

That wasn't entirely unexpected; after all, we had no idea how we would ever leave it. It was the second day after the attacking forces had invaded our position inside the alien city beneath the Europan ice. With no help within reach from our own political faction on Earth, Gilb ordered retreat into the Ballroom and we barricaded the doors. The room was immense, but fortunately had few entrances. A few of our people had left us and surrendered in the disorder of the retreat; Jeannine and I didn't get the chance, for we were watched too closely by Gilb and his officers.

It was cold in the Ballroom, and getting colder. Gilb authorized turning on the two portable heaters, since we had more energy cells with us than our group was likely to use in a year. It helped.

We also had with us several of the alien artifacts, now powered but still mysterious, for we had only just managed to activate them and had had no time to experiment. Jäger was with us, which was something; he knew the mysterious city's language better than anyone.

The three 10-foot-diameter balls still hung suspended above the floor. Each still showed a different scene: the field of yellowish grasses with something like trees nearby; the dusk beach scene; and the metallic room much like our own, with the cabinets, where we had seen the gray-clad human who had started at seeing us and then had run away. He had not returned, nor had anyone else. We knew that throwing small objects into the balls put them into the scenes; a spent energy cell thrown through the meadow gate — we were beginning to think of the balls as "gates" now — pushed through the growths and bounced on the grassy ground before coming to rest. The energy cell was still visible, and nothing had jumped on it or otherwise reacted to the experiment.

I turned to Jeannine, and we spoke of other cold and quiet times. It helped to distract us, while Jäger tried to make himself more useful at the other end of the room by continuing to experiment carefully with one of the artifacts.


Things were very quiet around the office.

That wasn't entirely unexpected; after all, it was January 2, and many people had taken the day off. I was puttering around with some small bits of programming on my to-do list, because my mind wasn't ready for anything big.

I had recently started getting "internal library" development requests, which was a real thrill for me even though the tasks were small. You see, our company didn't have an officially separate team whose job was to build software library infrastructure for the whole company, which I thought was a good thing. That organization style never made sense to me, nor I think to the Guru. But we did have a set of internal libraries for common things that were shared by several projects. The internal libraries had no single "owner," but items to be added or changed were reviewed by one of the more experienced developers. If we wrote something that was a likely candidate for reuse, we'd submit it to the shared libraries. Less often, someone would request a feature that wasn't in the shared area yet but probably should be, and someone capable would pick up the request and write it.

So I was thrilled because being asked to write an addition to the internal library branded me as "possibly capable." I was also thrilled because Bob wasn't ever asked, and this knowledge gave me a little ego boost. Ah, the vanity of youth.

The problem seemed easy: "Write a ConvertBase function that takes a string representing a number in base N and converts it to a string representing the same number in base M."

My first reaction was to write a hard-coded solution, something like this:

string ConvertBase( size_t base1, size_t base2,
                    const string& src )
{
  long value = 0;

  // Read a base base1 number from src
  for( int i = 0; i < src.size(); ++i )
  {
    // if src[i] is a valid base1 character,
    //  multiply value by base1 and add the next digit
    // else if src[i] is whitespace
    //  break
    // else
    //  throw logic_error
  }

  // Write a base base2 number to dest
  string dest;
  while( value > 0 )
  {
    // find highest base2 digit
    // append to dest
    // reduce value appropriately
  }
}

I had roughed in about that much and was still typing the last comment when a gentle throat-clearing behind me alerted me to the Guru's presence.

I froze. There was silence.

Then I heard a brief rustle of pages that I knew without looking was the Guru putting a marker into her book and closing it, and a calm low voice: "Goodeve, my child."

"Ah, goodeve, master," I replied. If she was in her Guru shtick, then Bob had to be nearby, and appearances were important to successfully bugging Bob.

"Your code," she gestured, walking around me into view and tapping on my display with her pen, "bears a striking resemblance to library request 247."

"Ah, yes, I hope it does," I acknowledged. "That's what I was working on. It looks like it's going to get kind of longish."

She nodded thoughtfully. There was another pause. After a moment she added: "Did you happen to notice library request 314?"

"Ah, er... no," I admitted.

"No harm done. Request 314 asks for a facility to read and write a number of arbitrary base from a text stream. I presume that whoever codes 314 will end up writing much the same code as you were about to write there. May I make a suggestion, my apprentice?"

"Sure. You want me to do 314 too?" I asked, hope rising. If it was an honor to be asked to write one shared library facility, imagine the honor of being asked to write two after such a short time on the team!

"Yes, but not immediately," said the Guru, arranging a wisp of graying hair behind her ear. "A principle of programming is that we often gain useful insights into our code by writing the test cases first. Beck, Fowler, Martin, and others preach this gospel to anyone who will listen and to many who will not. In this case, why not write the code for request 247 assuming that you already had the code for 314? Then write a simple test case for 247 and hard code just enough of a stub for 314 to make that test case compile. Finally, when you see in your 247 code the form that the solution to 314 should take, confirm that that form is acceptable to the people requesting 314, and do 314 too."

I blinked. "I think I got that. So I'll take a first cut at 247 that uses 314's not-yet-written facility, which will let me see what 314's facility ought to look like. Right?"

"Indeed."

"Okay." I thought for a moment and then started typing. I could assume that I had "a facility to read and write a number of arbitrary base from a text stream." All right. If I had that, I could use streams to translate between bases. After further thought, I eventually came up with this code:

string ConvertBase( size_t base1, size_t base2,
                    const string& src )
{
  stringstream s1( src );
  long value;

  if( !( s1 >> Num( base1, value ) ) || 
      !( s1 >> std::ws ).eof() )
    throw logic_error
      ( "src is not a valid number" );

  stringstream s2;
  if( !( s2 << Num( base2, value ) ) )
    throw logic_error
      ( "unexpected error emitting converted number" );

  return s2.str();
}

Then I wrote a simple test case, with just enough of a Num stub hardwired to make the case compile:

class Num
{
public:
  Num( size_t base, long& value ) :
    base_(base), value_(value) { }

  size_t Base() const { return base_;  }
  long& Value()       { return value_; }

private:
  size_t base_;
  long& value_;
};

istream& operator>>( istream& i, Num& n )
{
  string s;
  i >> s;
  // todo: really convert input to n's base_
  n.Value() = 255; 
  return i;
}

ostream& operator<<( ostream& o, const Num& /* n */ )
{
  // todo: really output n.value_ in n.base_
  return o << "FF"; 
}

int main()
{
  string result = ConvertBase( 10, 16, "255" );
  cout << result << endl;
  return result == "FF" ? 0 : 1;
}

After the compiler caught a few typos, I was satisfied that this skeletal attempt worked. Next, I knew I would have to more fully address request 314 by actually implementing << and >> for Nums.

I looked at my watch; it was well past quitting time, but I could still make my train and therefore my date with Anna. Request 314 could wait till the morning.


I looked at my watch; it was well past time for our turn to sleep, so we took the opportunity. There was periodic banging on the other side of one of the doors, presumably from the invading force, but that was all — so far. Unless something more happened, the strange balls, or gates, could wait till the morning. Although Gilb's people were still trying to use our portable comms gear to get a message to Earth, or to ships in transit I didn't know about, I had a feeling that the gates would be our only way out.

About the Authors

Jim Hyslop is a senior software designer at Leitch Technology International Inc. He can be reached at [email protected].

Herb Sutter is an independent consultant and secretary of the ISO/ANSI C++ standards committee. He is also one of the instructors of The C++ Seminar (<www.gotw.ca/cpp_seminar>). Herb can be reached at [email protected].


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.