Предполагая, что это значения, которые вы всегда используете для этого вычисления, я бы сделал что-то вроде:
D = I / (65535 / C);
или
D = I / 4369;
Поскольку C имеет значение 65535. Это поможет уменьшить вероятность превышения доступного диапазона целых чисел (т. Е. Если у вас есть только 16-битные целые числа без знака).
В более общем случае вы, если думаете, что существует риск того, что умножение I и C приведет к значению за пределами допустимого диапазона целочисленного типа, который вы используете (даже если конечный результат будет внутри этого диапазон) вы можете вычленить GCD числителя и знаменателя, как в:
INT I = 41828;
INT C = 15;
INT DEN = 65535;
INT GCDI = GCD(I, DEN);
DEN = DEN / GCDI;
I = I / GCDI;
INT GCDC = GCD(C, DEN);
DEN = DEN / GCDC;
C = C / GCDC;
INT D = (I * C) / DEN;
Где DEN - ваш знаменатель (в данном случае 65535). Это не даст вам правильного ответа во всех случаях, особенно если I и C оба взаимно просты с DEN и I * C> MAX_INT.
Что касается более крупного вопроса, который вы поднимаете, деление целочисленных значений всегда теряет десятичный компонент (эквивалентный функции floor). Единственный способ сохранить информацию, содержащуюся в том, что мы считаем «десятичной» частью, - это остаток, который можно вывести из модуля. Я настоятельно рекомендую вам не смешивать значения этих различных систем счисления. Целые числа - это просто целые числа. Если вам нужно, чтобы они были числами с плавающей точкой, вы должны использовать числа с плавающей точкой, а не целые числа. Если все, что вас интересует, это отображение десятичной части для пользователя (то есть вы на самом деле не используете ее для дальнейших вычислений), тогда вы могли бы написать подпрограмму для преобразования остатка в строку символов, представляющую остаток.