Вы правы, что с двойниками происходит что-то странное, то, что выводится на печать, не совпадает с содержимым переменной.
например:
groovy:000> "123.0001".toBigDecimal()
===> 123.0001
groovy:000> "123.0001".toDouble()
===> 123.0001
groovy:000> new BigDecimal("123.0001".toDouble())
===> 123.000100000000003319655661471188068389892578125
Обратите внимание, что урон наносится при преобразовании строки в double, а не при передаче double в BigDecimal. Подача двойного в BigDecimal просто обеспечивает простой способ увидеть, что на самом деле в двойном, потому что toString обманывает вас.
Как отмечает Джон Скит, точность здесь не вариант. Однако, предполагая, что значение, напечатанное на экране, является результатом вызова toString для double, вы должны иметь возможность получить bigDecimal, который не более ошибочен, чем версия toString для double, например, так:
groovy:000> d = "123.0001".toDouble()
===> 123.0001
groovy:000> d.toString()
===> 123.0001
groovy:000> new BigDecimal(d.toString())
===> 123.0001
Так что вам не нужно привлекать BigDecimal, на самом деле, вы можете просто сделать что-то вроде
groovy:000> d = 123.0001
===> 123.0001
groovy:000> s = d.toString()
===> 123.0001
groovy:000> s.substring(s.indexOf('.')).length() - 1
===> 4
Извините, что отредактировал ваш комментарий, отредактировав.
Кстати, здесь есть что-то близкое к ответу Стива, переведенному на отличный. (Я снял тест на десятичную точку, не найденную, потому что, если вы запустите это на машине с ошибочными локалями, поэтому для десятичной точки не используется точка, я предпочел бы ее взорвать, чем вернуть 0)
def getPlaces(d) {
s = d.toString()
s.substring(s.indexOf(".")).length() - 1
}