Thank you in advance!! Problem Writing programs that are completely portable acr
ID: 674245 • Letter: T
Question
Thank you in advance!! Problem Writing programs that are completely portable across different operating systems, operating system versions and hardware platforms is a challenging task. One of the difficulties encountered is a result of decisions made by hardware manufacturers about how they will store integer data in memory. Because these representations can differ from machine to machine, sharing binary data often cannot be done without modifying the way in which the data is stored or the way in which it is handled by one or more of the platforms Fortunately there is near-universal agreement among hardware manufacturers that addressable memory be ordered into 8-bit bytes. For integer data values that require more than 8-bits, such as the typical 2- byte, 4-byte, and 8-byte integer types available on most modern hardware, there is no such agreement and two incompatible storage schemes exist. The first stores integers as groups of consecutive 8-bit bytes with the least significant byte occupying the lowest memory location within the group and the most significant byte occupying the highest memory location. The second is just the reverse; the least significant byte is stored in the highest memory location within the group, and the most significant byte is stored in the lowest memory location. The computing industry has dubbed these schemes Little Endian and Big Endian, respectively (e.g., x86 processors use little endian and ATMega 328p uses big endian). There is also near-universal agreement that signed integers are stored using "two's complement representation, and you may assume that this is the case When binary integer data is shared between a Little Endian and Big Endian machine, a data conversion must be performed which involves reversing the bytes of the data. Once the bytes have been reversed the integer is then correctly interpreted by the hardware as the original value from the opposite-endian machine. The objective of this lab is to understand the different types of information representation (little vs. big endian) and to be able to write routines that perform the conversion required for different platform to communicate, and to display information to user in well-formatted manner. Problem: You are given the following table: int numberTable[ROWS][COLS]- (1,2,3,4,5,6,7,8,9H (7,2,8,4,5,4,7,3,1 (9,9,7,4,9,9,8,7,6 (6,3,7,4,5,4,5,7,9 Your program will read in these numbers and will create 4 unsigned integers, using the rows of the table above. For example, number 1 is 123,456,789; number two is 728,454,731; d so on. (Remember, that int are represented using multiple bytes.) Create a function named byteSwap that takes in each number and reverses the bytes converting from little endian to big endian or vice versa. Your program should also work with short and doubleExplanation / Answer
#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/endian.hpp>
#include <stdexcept>
enum endianness
{
little_endian,
big_endian,
network_endian = big_endian,
#if defined(BOOST_LITTLE_ENDIAN)
host_endian = little_endian
#elif defined(BOOST_BIG_ENDIAN)
host_endian = big_endian
#else
#error "unable to determine system endianness"
#endif
};
namespace detail {
template<typename T, size_t sz>
struct swap_bytes
{
inline T operator()(T val)
{
throw std::out_of_range("data size");
}
};
template<typename T>
struct swap_bytes<T, 1>
{
inline T operator()(T val)
{
return val;
}
};
template<typename T>
struct swap_bytes<T, 2>
{
inline T operator()(T val)
{
return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8));
}
};
template<typename T>
struct swap_bytes<T, 4>
{
inline T operator()(T val)
{
return ((((val) & 0xff000000) >> 24) |
(((val) & 0x00ff0000) >> 8) |
(((val) & 0x0000ff00) << 8) |
(((val) & 0x000000ff) << 24));
}
};
template<>
struct swap_bytes<float, 4>
{
inline float operator()(float val)
{
uint32_t mem =swap_bytes<uint32_t, sizeof(uint32_t)>()(*(uint32_t*)&val);
return *(float*)&mem;
}
};
template<typename T>
struct swap_bytes<T, 8>
{
inline T operator()(T val)
{
return ((((val) & 0xff00000000000000ull) >> 56) |
(((val) & 0x00ff000000000000ull) >> 40) |
(((val) & 0x0000ff0000000000ull) >> 24) |
(((val) & 0x000000ff00000000ull) >> 8 ) |
(((val) & 0x00000000ff000000ull) << 8 ) |
(((val) & 0x0000000000ff0000ull) << 24) |
(((val) & 0x000000000000ff00ull) << 40) |
(((val) & 0x00000000000000ffull) << 56));
}
};
template<>
struct swap_bytes<double, 8>
{
inline double operator()(double val)
{
uint64_t mem =swap_bytes<uint64_t, sizeof(uint64_t)>()(*(uint64_t*)&val);
return *(double*)&mem;
}
};
template<endianness from, endianness to, class T>
struct do_byte_swap
{
inline T operator()(T value)
{
return swap_bytes<T, sizeof(T)>()(value);
}
};
// specialisations when attempting to swap to the same endianess
template<class T> struct do_byte_swap<little_endian, little_endian, T> { inline T operator()(T value) { return value; } };
template<class T> struct do_byte_swap<big_endian, big_endian, T> { inline T operator()(T value) { return value; } };
} // namespace detail
template<endianness from, endianness to, class T>
inline T byte_swap(T value)
{
// ensure the data is only 1, 2, 4 or 8 bytes
BOOST_STATIC_ASSERT(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
// ensure we're only swapping arithmetic types
BOOST_STATIC_ASSERT(boost::is_arithmetic<T>::value);
return detail::do_byte_swap<from, to, T>()(value);
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.